Spring Cloud系列文,Feign整合Ribbon和Hysrix

刺骨的言语ヽ痛彻心扉 2021-09-19 15:26 268阅读 0赞

在本博客之前的Spring Cloud系列里,我们讲述了Feign的基本用法,这里我们将讲述下Feign整合Ribbon实现负载均衡以及整合Hystrix实现断路保护效果的方式。

1 准备Eureka服务器以及多个服务提供者

  1. 这里,我们将重用之前博文里讲过的案例,提供的两个(即主从)Eureka服务项目以及三个服务提供者的项目。随后在此基础上,在服务调用者的项目中,通过Feign以负载均衡的方式调用三个服务提供者所提供的sayHello方法。

2 在客户端引入Ribbon

在FeignDemo-ServiceCaller项目里开发Fegin整合Ribbon,具体的步骤如下。

在pom.xml中,引入Ribbon依赖包,关键代码如下。

  1. 1 <dependency>
  2. 2 <groupId>org.springframework.cloud</groupId>
  3. 3 <artifactId>spring-cloud-ribbon</artifactId>
  4. 4 </dependency>
  5. ControllerForFeignRibbon.java中,编写FeignRibbon负载均衡的方式调用服务的代码。

复制代码

  1. //省略必要的package和import的代码
  2. //这和Ribbon Provider中的applicationname一致
  3. @FeignClient(value = "sayHelloAvoidCopy")
  4. interface FeignClientRibbonTool{
  5. @RequestMapping(method = RequestMethod.GET, value = "/sayHello/{username}/avoidCopy")
  6. String sayHelloAsRibbon(@PathVariable("username") String username);
  7. }
  8. @RestController
  9. public class ControllerForFeignRibbon {
  10. private FeignClientRibbonTool tool;
  11. @RequestMapping(value = "/callHelloAsRibbon/{username}", method = RequestMethod.GET)
  12. public String callHelloAsRibbon(@PathVariable("username") String username) {
  13. return tool.sayHelloAsRibbon(username);
  14. }
  15. }

复制代码

  1. 在上述代码里,,我们定义了一个名为FeignClientRibbonTool的接口;在第3行中,我们通过@FeignClient注解指定了该Feign接口将会调用名为sayHello的服务。请注意,这里的sayHello命名需要和EurekaRibbonDemo-ServiceProviderOne等项目中application.yml中的相应配置一致。
  2. 在第10行中,我们通过@RestController注解定义了一个名为ControllerForFeignRibbon的控制器类,在其中的第14行的callHelloAsRibbon中,我们是通过Feign接口中的sayHelloAsRibbon方法调用服务的。
  3. application.yml中,编写Ribbon的相关配置信息,关键代码如下。
  4. 1 sayHello:
  5. 2 ribbon:
  6. 3 listOfServer: http://localhost:1111/,http://localhost:2222/,http://localhost:3333
  7. 4 ConnectionsTimeout: 1000
  8. 5 ribbon:
  9. 6 ConnectionsTimeout: 2000
  10. 在第1~4行,我们通过配置指定了基于ribbon的多台服务器,它们将以负载均衡的方式承担请求url,而且还指定了连接超时的时间。从第1行我们能看到,这个配置是针对sayHello这个服务实例的。而在第5行和第6行,我们配置了全局性的ribbon属性,这里也配置了连接超时时间。
  11. 完成开发后,启动定义在表6.2中的两台Eureka服务器、三台服务提供者和一台服务调用者程序后,在浏览器中多次输入http://localhost:8080/callHelloAsRibbon/Peter以调用服务,这时我们能看到有如下输出。从输出结果来看,我们以Feign的形式调用的请求确实被均衡地转发到3台服务提供者的机器上。
  12. 1 Hello Ribbon, there are Server1, my name is:Peter
  13. 2 Hello Ribbon, there are Server2, my name is:Peter
  14. 3 Hello Ribbon, there are Server3, my name is:Peter
  15. 这里我们来总结一下Feign整合Ribbon的要点。
  16. 第一,多个服务器提供者的实例名应当一致,比如这里都是sayHello
  17. 第二,在Feign的接口中,是通过@FeignClient的注解调用服务提供者的方法的。
  18. 第三,这里我们是在application.yml配置文件中指定Ribbon的各种参数,也可以通过@Configuration注解在Java文件中配置Ribbon的参数。

3 在客户端引入Hystrix(Feigh整合Hystrix)

  1. 在通过Feign调用服务时,同样不能保证服务一定可用,为了提升客户体验,这里可以通过引入Hystrix对访问请求进行“容错保护”。
  2. FeignDemo-ServiceCallerpom.xml中,增加Hystrix的依赖包,关键代码如下。
  3. 1 <dependency>
  4. 2 <groupId>org.springframework.cloud</groupId>
  5. 3 <artifactId>spring-cloud-hystrix</artifactId>
  6. 4 </dependency>

还是在FeignDemo-ServiceCaller项目的application.yml配置文件中,通过如下配置项启动Hystrix模式,关键代码如下。

  1. 1 feign:
  2. 2 hystrix:
  3. 3 enabled: true
  4. 此外,还可以通过如下代码配置针对sayHelloServiceProvider服务的hystrix参数。其中,第3行指定了hystrix所作用的服务名,第7行指定了请求时间一旦超过1000毫秒(也就是1秒),就会启动熔断模式,调用定义在回退方法中的业务动作。

复制代码

  1. 1 hystrix:
  2. 2 command:
  3. 3 sayHelloServiceProvider:
  4. 4 execution:
  5. 5 isolations:
  6. 6 threads:
  7. 7 timeoutInMilliseconds: 1000

复制代码

  1. 在启动类ServiceCallerApp.java中,增加启动hystrix断路器的注解,如第5行所示,这个类的关键代码如下。

复制代码

  1. 1 //省略必要的package和import方法
  2. 2 EnableFeignClients
  3. 3 @EnableDiscoveryClient
  4. 4 @SpringBootApplication
  5. 5 @EnableCircuitBreakers
  6. 6 public class ServiceCallerApp
  7. 7 {
  8. 8 //省略其他代码
  9. 9 }

复制代码

新建一个名为ControllerForFeignHystrix.java的控制器类,代码如下。

复制代码

  1. 1 //省略必要的package和import代码
  2. 2 @FeignClient(value = "sayHelloServiceProvider",fallback=FeignClientHystrixToolFallback.class)
  3. 3 interface FeignClientHystrixTool{
  4. 4 @RequestMapping(method = RequestMethod.GET, value = "/hello/{name}")
  5. 5 String sayHelloInClient(@RequestParam("name") String name);
  6. 6 }

复制代码

在第3行中,我们定义了一个名为FeignClientHystrixTool的接口;在第2行的注解中,我们定义了它将以Feign的形式调用sayHelloServiceProvider中的服务,并且通过fallback配置指定一旦出现调用异常,将调用FeignClientHystrixToolFallback类中的回退方法。

  1. 7 @Component
  2. 8 class FeignClientHystrixToolFallback implements FeignClientHystrixTool{
  3. 9 public String sayHelloInClient(String name)
  4. 10 { return "In Fallback Function."; }
  5. 11 }
  6. 在第8行的FeignClientHystrixToolFallback类中,我们将定义针对FeignClientHystrixTool接口的回退方法。
  7. 注意该类必须和第2行中fallback指定的类同名,而且,该类需要实现(implementsFeignClientHystrixTool接口,在其中的sayHelloInClient方法中定义了回退动作,这里的动作是打印一段话。

复制代码

  1. 12 @RestController
  2. 13 public class ControllerForFeignHystrix {
  3. 14 @Autowired
  4. 15 private FeignClientHystrixTool tool;
  5. 16 @RequestMapping(value = "/callHelloAsHystrix/{username}", method = RequestMethod.GET)
  6. 17 public String callHelloAsHystrix(@PathVariable("username") String username)
  7. 18 { return tool.sayHelloInClient(username);}
  8. 19 }

复制代码

  1. 在第13行中,我们定义了一个包含@RestController注解的控制器类ControllerForFeignHystrix,在其中第17行的callHelloAsHystrix方法中,我们是以Feign的形式调用sayHelloInClient方法的。
  2. 至此,完成代码的编写工作。我们依次启动FeignDemo-ServerFeignDemo-ServiceProviderFeignDemo-ServiceCaller项目,随后在浏览器中输入http://localhost:8080/callHelloAsHystrix/Peter,此时能看到“hello Peter”的输出,这个是正常的调用流程。
  3. 如果我们关闭FeignDemo-ServiceProvider项目,也就是说sayHelloServiceProvider服务不可用了,如果再次在浏览器中输入[http://localhost:8080/callHelloAsHystrix/Peter][http_localhost_8080_callHelloAsHystrix_Peter],此时就会走熔断保护的流程,触发FeignClientHystrixToolFallback 类中的sayHelloInClient方法,在浏览器中输出“In Fallback Function“的字样。

如果你对编程感兴趣或者想往编程方向发展,可以关注微信公众号【筑梦编程】,大家一起交流讨论!小编也会每天定时更新既有趣又有用的编程知识!

发表评论

表情:
评论列表 (有 0 条评论,268人围观)

还没有评论,来说两句吧...

相关阅读