1,在上篇博文中,已经实现了feign 客户端来远程调用接口的功能,因为feign 客户端在springcloud 开发过程中是比较常用的方式
https://www.cnblogs.com/pickKnow/p/11385656.html
2,上一篇博文中的架构,比较简单,直接使用feign 客户端没有重构的话,代码比较冗余。例如,member 服务中调用FeignMember 中的 getOrder 接口,FeignOrder 中的接口的具体实现在order 服务中的getOrder 中来实现
这样的代码比较冗余,如果有很多方法,就得写好多的接口。。。
@FeignClient(name = "app-aiyuesheng-order") public interface OrderFeign { @RequestMapping("/getOrder") public String getOrder();
。。。。
。。。。
如果有好多接口,这边得写很多,代码很冗余 }
3,springcloud 项目中,重构feign 客户端
项目的最终的目录结构
-----eureka: 单独的项目,eureka 注册中心
-----springcloud-parents: 父项目,里面是共同的依赖,maven project 的打包类型选择pom
----------springcloud-api-service :子moduel.也是pom 类型,api 接口,没有实现
---------------springcloud-api-member-service: 子module:jar 类型,具体的member 的接口
---------------springcloud-api-order-service: 子module:jar 类型,具体的order 的接口
----------springcloud-api-member-impl-service: 子module,jar 类型,member api 的具体实现
----------springcloud-api-order-impl-service: 子module,jar 类型,order api 的具体实现
第一步:
springcloud-parents:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> </parent> <!-- 管理依赖 --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Finchley.M7</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- SpringBoot整合Web组件 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- SpringBoot整合eureka客户端 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- SpringBoot整合fegnin客户端 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> <!-- 注意: 这里必须要添加, 否者各种依赖有问题 --> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/libs-milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories>
第二步:
springcloud-api-order-service: order 服务的api 接口, @RequestMapping("/getOrder") 是为了Feign 客户端来调用
public interface IOrderService { @RequestMapping("/getOrder") public Order getOrder(String orderId); }
第三步:
springcloud-api-order-impl-service: order 服务的api 接口的具体实现,因为在不同的项目里面,所以要在maven里面把springcloud-api-order-service 的依赖加进去
<!--把order的接口引入过来 --> <dependencies> <dependency> <groupId>com.aiyuesheng</groupId> <artifactId>springcloud-api-order-service</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies>
开始写接口的实现:
@RestController public class OrderServiceImpl implements IOrderService { @RequestMapping("/getOrder") public Order getOrder(String orderId) { Order order = new Order(); order.setOrderId(orderId); order.setOrderName("订单名称"); return order; } }
第四步:在springcloud-api-member-impl-service 里面开始掉用order 服务,使用feign 客户端,
创建了 OrderServiceFeign,指定需要调用的服务名称
@RestController public class MemberServiceImpl { @Autowired private OrderServiceFeign orderServiceFeign; //通过feign 客户端来实现远程调用 @RequestMapping("/getOrder") public Order getOrder(String orderId){ Order order = orderServiceFeign.getOrder(orderId); return order; } }
指定了调用的服务别名:app-aiyuesheng-order
@FeignClient(value = "app-aiyuesheng-order") public interface OrderServiceFeign extends IOrderService { }
同时继承了IOrderService,相当于这部分代码不用写了,写出来就是冗余的代码
@RequestMapping("/getOrder") public Order getOrder(String orderId);
但是需要在maven 里面加入依赖:
<dependencies> <dependency> <groupId>com.aiyuesheng</groupId> <artifactId>springcloud-api-order-service</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies>
这样,就完成了代码的重构,以及用Feign 客户端实现远程调用
主要Feign 客户端是默认支持Ribbon 客户端负载均衡器的,所以,当服务集群的时候,也能够轮询式的访问
如果使用Feign 客户端远程调用接口的时间过长怎么处理呢?可以加入超时时间的配置:
###设置feign客户端超时时间
ribbon:
###指的是建立连接所用的时间,适用于网络状况正常的情况下,两端连接所用的时间。
ReadTimeout: 5000
###指的是建立连接后从服务器读取到可用资源所用的时间。
ConnectTimeout: 5000