在本博客之前的 Spring Cloud 系列里, 我们讲述了 Feign 的基本用法, 这里我们将讲述下 Feign 整合 Ribbon 实现负载均衡以及整合 Hystrix 实现断路保护效果的方式.
1 准备 Eureka 服务器以及多个服务提供者
这里, 我们将重用之前博文里讲过的案例, 提供的两个 (即主从)Eureka 服务项目以及三个服务提供者的项目. 随后在此基础上, 在服务调用者的项目中, 通过 Feign 以负载均衡的方式调用三个服务提供者所提供的 sayHello 方法.
2 在客户端引入 Ribbon
在 FeignDemo-ServiceCaller 项目里开发 Fegin 整合 Ribbon, 具体的步骤如下.
在 pom.xml 中, 引入 Ribbon 依赖包, 关键代码如下.
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-ribbon</artifactId>
- </dependency>
在 ControllerForFeignRibbon.java 中, 编写 Feign 以 Ribbon 负载均衡的方式调用服务的代码.
- // 省略必要的 package 和 import 的代码
- // 这和 Ribbon Provider 中的 applicationname 一致
- @FeignClient(value = "sayHelloAvoidCopy")
- interface FeignClientRibbonTool{
- @RequestMapping(method = RequestMethod.GET, value = "/sayHello/{username}/avoidCopy")
- String sayHelloAsRibbon(@PathVariable("username") String username);
- }
- @RestController
- public class ControllerForFeignRibbon {
- private FeignClientRibbonTool tool;
- @RequestMapping(value = "/callHelloAsRibbon/{username}", method = RequestMethod.GET)
- public String callHelloAsRibbon(@PathVariable("username") String username) {
- return tool.sayHelloAsRibbon(username);
- }
- }
在上述代码里,, 我们定义了一个名为 FeignClientRibbonTool 的接口; 在第 3 行中, 我们通过 @FeignClient 注解指定了该 Feign 接口将会调用名为 sayHello 的服务. 请注意, 这里的 sayHello 命名需要和 EurekaRibbonDemo-ServiceProviderOne 等项目中 application.YAML 中的相应配置一致.
在第 10 行中, 我们通过 @RestController 注解定义了一个名为 ControllerForFeignRibbon 的控制器类, 在其中的第 14 行的 callHelloAsRibbon 中, 我们是通过 Feign 接口中的 sayHelloAsRibbon 方法调用服务的.
在 application.YAML 中, 编写 Ribbon 的相关配置信息, 关键代码如下.
- sayHello:
- ribbon:
- listOfServer: http://localhost:1111/,http://localhost:2222/,http://localhost:3333
- ConnectionsTimeout: 1000
- ribbon:
- ConnectionsTimeout: 2000
在第 1~4 行, 我们通过配置指定了基于 ribbon 的多台服务器, 它们将以负载均衡的方式承担请求 url, 而且还指定了连接超时的时间. 从第 1 行我们能看到, 这个配置是针对 sayHello 这个服务实例的. 而在第 5 行和第 6 行, 我们配置了全局性的 ribbon 属性, 这里也配置了连接超时时间.
完成开发后, 启动定义在表 6.2 中的两台 Eureka 服务器, 三台服务提供者和一台服务调用者程序后, 在浏览器中多次输入 http://localhost:8080/callHelloAsRibbon/Peter 以调用服务, 这时我们能看到有如下输出. 从输出结果来看, 我们以 Feign 的形式调用的请求确实被均衡地转发到 3 台服务提供者的机器上.
- Hello Ribbon, there are Server1, my name is:Peter
- Hello Ribbon, there are Server2, my name is:Peter
- Hello Ribbon, there are Server3, my name is:Peter
这里我们来总结一下 Feign 整合 Ribbon 的要点.
第一, 多个服务器提供者的实例名应当一致, 比如这里都是 sayHello.
第二, 在 Feign 的接口中, 是通过 @FeignClient 的注解调用服务提供者的方法的.
第三, 这里我们是在 application.YAML 配置文件中指定 Ribbon 的各种参数, 也可以通过 @Configuration 注解在 Java 文件中配置 Ribbon 的参数.
3 在客户端引入 Hystrix(Feigh 整合 Hystrix)
在通过 Feign 调用服务时, 同样不能保证服务一定可用, 为了提升客户体验, 这里可以通过引入 Hystrix 对访问请求进行 "容错保护".
在 FeignDemo-ServiceCaller 的 pom.xml 中, 增加 Hystrix 的依赖包, 关键代码如下.
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-hystrix</artifactId>
- </dependency>
还是在 FeignDemo-ServiceCaller 项目的 application.YAML 配置文件中, 通过如下配置项启动 Hystrix 模式, 关键代码如下.
- feign:
- hystrix:
- enabled: true
此外, 还可以通过如下代码配置针对 sayHelloServiceProvider 服务的 hystrix 参数. 其中, 第 3 行指定了 hystrix 所作用的服务名, 第 7 行指定了请求时间一旦超过 1000 毫秒 (也就是 1 秒), 就会启动熔断模式, 调用定义在回退方法中的业务动作.
- hystrix:
- command:
- sayHelloServiceProvider:
- execution:
- isolations:
- threads:
- timeoutInMilliseconds: 1000
在启动类 ServiceCallerApp.java 中, 增加启动 hystrix 断路器的注解, 如第 5 行所示, 这个类的关键代码如下.
- // 省略必要的 package 和 import 方法
- EnableFeignClients
- @EnableDiscoveryClient
- @SpringBootApplication
- @EnableCircuitBreakers
- public class ServiceCallerApp
- {
- // 省略其他代码
- }
新建一个名为 ControllerForFeignHystrix.java 的控制器类, 代码如下.
- // 省略必要的 package 和 import 代码
- @FeignClient(value = "sayHelloServiceProvider",fallback=FeignClientHystrixToolFallback.class)
- interface FeignClientHystrixTool{
- @RequestMapping(method = RequestMethod.GET, value = "/hello/{name}")
- String sayHelloInClient(@RequestParam("name") String name);
- }
在第 3 行中, 我们定义了一个名为 FeignClientHystrixTool 的接口; 在第 2 行的注解中, 我们定义了它将以 Feign 的形式调用 sayHelloServiceProvider 中的服务, 并且通过 fallback 配置指定一旦出现调用异常, 将调用 FeignClientHystrixToolFallback 类中的回退方法.
- @Component
- class FeignClientHystrixToolFallback implements FeignClientHystrixTool{
- public String sayHelloInClient(String name)
- { return "In Fallback Function."; }
- }
在第 8 行的 FeignClientHystrixToolFallback 类中, 我们将定义针对 FeignClientHystrixTool 接口的回退方法.
注 意
该类必须和第 2 行中 fallback 指定的类同名, 而且, 该类需要实现 (implements)FeignClientHystrixTool 接口, 在其中的 sayHelloInClient 方法中定义了回退动作, 这里的动作是打印一段话.
- @RestController
- public class ControllerForFeignHystrix {
- @Autowired
- private FeignClientHystrixTool tool;
- @RequestMapping(value = "/callHelloAsHystrix/{username}", method = RequestMethod.GET)
- public String callHelloAsHystrix(@PathVariable("username") String username)
- { return tool.sayHelloInClient(username);}
- }
在第 13 行中, 我们定义了一个包含 @RestController 注解的控制器类 ControllerForFeignHystrix, 在其中第 17 行的 callHelloAsHystrix 方法中, 我们是以 Feign 的形式调用 sayHelloInClient 方法的.
至此, 完成代码的编写工作. 我们依次启动 FeignDemo-Server,FeignDemo-ServiceProvider 和 FeignDemo-ServiceCaller 项目, 随后在浏览器中输入 http://localhost:8080/callHelloAsHystrix/Peter, 此时能看到 "hello Peter" 的输出, 这个是正常的调用流程.
如果我们关闭 FeignDemo-ServiceProvider 项目, 也就是说 sayHelloServiceProvider 服务不可用了, 如果再次在浏览器中输入 http://localhost:8080/callHelloAsHystrix/Peter , 此时就会走熔断保护的流程, 触发 FeignClientHystrixToolFallback 类中的 sayHelloInClient 方法, 在浏览器中输出 "In Fallback Function" 的字样.
本文谢绝转载, 如果要代码, 请和作者联系. Spring Cloud 相关博文如下:
Spring Cloud 微服务系列文, 服务调用框架 Feign
Spring Cloud 微服务系列文, Hystrix 与 Eureka 的整合
架构师系列文: 通过 Spring Cloud 组件 Hystrix 合并请求
架构师入门: Spring Cloud 系列, Hystrix 与 Eureka 的整合
Hystrix 针对不可用服务的保护机制以及引入缓存
通过案例了解 Hystrix 的各种基本使用方式
Ribbon 整合 Eureka 组件, 以实现负载均衡
Spring Clould 负载均衡重要组件: Ribbon 中重要类的用法
架构师入门: 搭建双注册中心的高可用 Eureka 架构 (基于项目实战)
架构师入门: 搭建基本的 Eureka 架构 (从项目里抽取)
借助 Maven 入手 Spring Boot 第一个程序
来源: https://www.cnblogs.com/JavaArchitect/p/10928778.html