Spring Cloud(4):Feign的使用
2019-05-17 00:03:02来源:博客园 阅读 ()
基于上一篇文章:https://www.cnblogs.com/xuyiqing/p/10867739.html
使用Ribbon实现了订单服务调用商品服务的Demo
下面介绍如何使用Feign实现这个Demo
Feign:伪RPC客户端,底层基于HTTP
在订单服务的POM中加入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
并在启动类中加入注解,这里已经加入的Ribbon可以保留
package org.dreamtech.orderservice; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate; @SpringBootApplication @EnableFeignClients public class OrderServiceApplication { public static void main(String[] args) { SpringApplication.run(OrderServiceApplication.class, args); } @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } }
Feign接口
package org.dreamtech.orderservice.service; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @FeignClient(name = "product-service") public interface ProductClient { @RequestMapping("/api/product/find") String findById(@RequestParam(value = "id")int id); }
使用
package org.dreamtech.orderservice.service.impl; import com.fasterxml.jackson.databind.JsonNode; import org.dreamtech.orderservice.domain.ProductOrder; import org.dreamtech.orderservice.service.ProductClient; import org.dreamtech.orderservice.service.ProductOrderService; import org.dreamtech.orderservice.utils.JsonUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import java.util.Date; import java.util.Map; import java.util.UUID; @Service public class ProductOrderServiceImpl implements ProductOrderService { private final ProductClient productClient; @Autowired public ProductOrderServiceImpl(ProductClient productClient) { this.productClient = productClient; } @Override public ProductOrder save(int userId, int productId) { String response = productClient.findById(productId); JsonNode jsonNode = JsonUtils.str2JsonNode(response); ProductOrder productOrder = new ProductOrder(); productOrder.setCreateTime(new Date()); productOrder.setUserId(userId); productOrder.setTradeNo(UUID.randomUUID().toString()); productOrder.setProductName(jsonNode.get("name").toString()); productOrder.setPrice(Integer.parseInt(jsonNode.get("price").toString())); return productOrder; } }
工具类
package org.dreamtech.orderservice.utils; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; public class JsonUtils { private static final ObjectMapper objectMapper = new ObjectMapper(); public static JsonNode str2JsonNode(String str) { try { return objectMapper.readTree(str); } catch (IOException e) { return null; } } }
重启Eureka Server和多个product-service:
访问http://localhost:8781/api/order/save?user_id=1&product_id=1,成功
使用注意:
1.Feign的路由和服务的路由必须一致(如这里的/api/product/find)
2.注意服务名的一致
3.参数必须加入@RequestParam确保参数名和服务的一致
4.如果服务的参数加入了@RequestBody,Feign客户端也要加入@RequestBody并修改为POST方式
5.这里获取到JSON直接解析,实际情况可以抽取公共实体类为JAR包引入返回实体类
FeignClient原理:
查看Clien类可以发现,Feign的实现是通过HTTP形式:
HttpURLConnection convertAndSend(Request request, Options options) throws IOException { HttpURLConnection connection = (HttpURLConnection)(new URL(request.url())).openConnection(); if (connection instanceof HttpsURLConnection) { HttpsURLConnection sslCon = (HttpsURLConnection)connection; if (this.sslContextFactory != null) { sslCon.setSSLSocketFactory(this.sslContextFactory); } if (this.hostnameVerifier != null) { sslCon.setHostnameVerifier(this.hostnameVerifier); } }
Client的实现类中:
发现Feign调用了Ribbon做负载均衡
public Response execute(Request request, Options options) throws IOException { try { URI asUri = URI.create(request.url()); String clientName = asUri.getHost(); URI uriWithoutHost = cleanUrl(request.url(), clientName); RibbonRequest ribbonRequest = new RibbonRequest(this.delegate, request, uriWithoutHost); IClientConfig requestConfig = this.getClientConfig(options, clientName); return ((RibbonResponse)this.lbClient(clientName).executeWithLoadBalancer(ribbonRequest, requestConfig)).toResponse(); } catch (ClientException var8) { IOException io = this.findIOException(var8); if (io != null) { throw io; } else { throw new RuntimeException(var8); } } }
处理超时问题:实际情况服务和调用者之间的通信可能较慢,这时候Feign会报错
如下配置Feign超时实际为10秒
feign: client: config: default: connectTimeout: 10000 readTimeout: 10000
Feign默认超时为1秒
Feign和Ribbon的对比:
1.Feign里面包含Ribbon,Feign的负载均衡由Ribbon实现
2.Feign更方便,可以和Hystrix结合
原文链接:https://www.cnblogs.com/xuyiqing/p/10869026.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- Spring系列.ApplicationContext接口 2020-06-11
- springboot2配置JavaMelody与springMVC配置JavaMelody 2020-06-11
- 给你一份超详细 Spring Boot 知识清单 2020-06-11
- SpringBoot 2.3 整合最新版 ShardingJdbc + Druid + MyBatis 2020-06-11
- 掌握SpringBoot-2.3的容器探针:实战篇 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash