ToB企服应用市场:ToB评测及商务社交产业平台

标题: 熔断、限流、降级 —— SpringCloud Hystrix [打印本页]

作者: 张国伟    时间: 2024-9-5 14:32
标题: 熔断、限流、降级 —— SpringCloud Hystrix
概述

Hystrix 为 微服务架构提供了一整套服务隔离、服务熔断和服务降级的解决方案。它是熔断器的一种实现,主要用于解决微服务架构的高可用及服务雪崩等题目
Hystrix 的特性如下:

Hystrix 服务降级流程



Hystrix 应用

Hystrix 的利用主要分为服务熔断、服务降级和服务监控三个方面
在 pom.xml 文件中引入 Hystrix 依赖,其中,spring-cloud-slarter-netflix-hystrix 和 hystrix-javanica 为 Hystrix 服务熔断所需的依赖,spring-cloud-netflix-hystrix-dashboard 为 Hystrix 服务监控所需的依赖
  1. <dependency>
  2.   <groupId>org.springframework.boot</groupId>
  3.   <artifactId>spring-boot-starter-actuator</artifactId>
  4. </dependency>
  5. <dependency>
  6.   <groupId>org.springframework.cloud</groupId>
  7.   <artifactId>spring-cloud-starter-eureka</artifactId>
  8.   <version>1.4.6.RELEASE</version>
  9. </dependency>
  10. <dependency>
  11.   <groupId>org.springframework.cloud</groupId>
  12.   <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
  13.   <version>1.4.6.RELEASE</version>
  14. </dependency>
  15. <dependency>
  16.   <groupId>com.netflix.hystrix</groupId>
  17.   <artifactId>hystrix-javanica</artifactId>
  18.   <version>RELEASE</version>
  19. </dependency>
  20. <dependency>
  21.   <groupId>org.springframework.cloud</groupId>
  22.   <artifactId>spring-cloud-netflix-hystrix-dashboard</artifactId>
  23.   <version>1.4.6.RELEASE</version>
  24. </dependency>
复制代码
通过 @EnableHystrix 注解开启对服务熔断的支持,通过 @EnableHystrixDashboard 注解开启对服务监控的支持。注意,Hystrix 一样寻常和服务发现配合利用,这里使 @EnableEurekaClient 开启了对服务发现客户端的支持
  1. @SpringBootApplication
  2. @EnableEurekaClient
  3. @EnableHystrix
  4. @EnableHystrixDashboard
  5. public class HystrixServiceApplication {
  6.   public static void main(String[] args) {
  7.     SpringApplication.run(HystrixServiceApplication.class, args);
  8.   }
  9.   @Bean
  10.   public IRule ribbonRule() {
  11.     return new RandomRule();
  12.   }
  13.   @Bean
  14.   @LoadBalanced
  15.   public RestTemplate restTemplate() {
  16.     return new RestTemplate();
  17.   }
  18. }
复制代码
配置 application.properties 文件
  1. #服务名
  2. spring.application.name=hystrix
  3. #服务的端口
  4. server.port=9005
  5. #注册中心的地址
  6. eureka.client.serviceUrl.defaultZone=http://localhost:9001/eureka/
  7. eureka.client.registry-fetch-interval-seconds=30
复制代码
服务熔断和降级,界说了一个远程调用的方法 hystrixHandler(),并通过 @HystrixCommand(fallbackMethod="exceptionHandler") 在方法上界说了一个服务降级的命令,当远程方法调用失败时,Hystrix 会自动调用 fallbackMethod 来完成服务熔断和降级,这里会调用 exceptionHandler 方法
  1. @Autowired
  2. private RestTemplate restTemplate;
  3. //定义服务降级命令
  4. @HystrixCommand(fallbackMethod = "exceptionHandler")
  5. @RequestMapping(value = "/service/hystrix", method = RequestMethod.GET)
  6. public String hystrixHandler() {
  7.   return restTemplate.getForEntity("http://EUREKA-CLIENT/serviceProducer", String.class).getBody();
  8. }
  9. public String exceptionHandler() {
  10.   return "提供者服务挂了";
  11. }
复制代码
异步处理

上节中的远程调用请求必须等到网络请求返回结果后,才会执行背面的代码,即阻塞运行。而在现实利用过程中,应用程序常常希望利用非阻塞 IO 来更优雅地实现功能.Hyslrix 为非阻塞 IO 提供了两种实现方式,分别是表示将来式的 Future 和表示回调式的 Callable
1. Future

界说 HystrixCommand
  1. public class CommandFuture extends HystrixCommand<String> {
  2.   private String name;
  3.   private RestTemplate restTemplate;
  4.   public CommandFuture(String name, RestTemplate restTemplate) {
  5.     super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"))
  6.                 //1:通过 HystrixCommandKey 工厂定义依赖的名称
  7.                 .andCommandKey(HystrixComnandKey.Factory.asKey("HelloWorld"))
  8.                 //2:通过 HystrixThreadPoolKey 工厂定义线程池的名称
  9.                 .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("HelloWorldPool")));
  10.     this.name = name;
  11.     this.restTemplate = restTemplate;
  12.   }
  13.   //3:定义远程调用的方法体
  14.   @Override
  15.   protected String run() {
  16.     String result = restTemplate.getForEntity("http://EUREKA-CLIENT/serviceProducer", String.class).getBody();
  17.     return result;
  18.   }
  19.   //4:服务降级的处理逻辑
  20.   @Override
  21.   protected String getFallback() {
  22.     return "远程服务异常";
  23.   }
  24. }
复制代码
以上代码通过继承 HystrixCommand 界说了一个 CommandFuture 来实现异步请求,其中,正常业务执行的逻辑在覆写的 run() 方法体中被执行,服务降级的方法在 getFallback() 中被执行。需要注意的是,这里利用 andCommandKey(HystrixCommandKey.Factory.asKey("HelloWorld")) 实现了利用 HystrixCommandKey 工厂界说依赖的名称,每个 CommandKey 都代表一个依赖抽象,相同的依赖要利用相同的 CommandKey 名称。依赖隔离的本质敦是对相同
CommandKey 的依赖进行离,利用 andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("HelloWorldPool")) 实现了基于 HystrixThreadPoolKey 工厂界说线程池的名称。当对同一业务的依赖进行资源隔离时,利用 CommandGroup 进行区分,但是当对同一依赖进行差异的远程调用时(比方,一个是 Redis 服务,一个是 HTTP 服务),则可以利用 HystrixThreadPoolKey 进行隔离区分
利用 HystrixCommand
  1. @RequeatMapping(value = "/service/hystrix/future", method = RequestMethod.GET)
  2. public String hystrixFutureHandler() throws ExecutionException, InterruptedException {
  3.   //定义基于Future的异步调用,请求会以队列的形式在线程池中被执行
  4.   Future<String> future = new CommandFuture("future", restTemplate).queue();
  5.   return future.get();
  6. }
复制代码
2. Callable

预界说一个回调任务,Callable 在发出请求后,主线程继续执行,在请求执行完成并返回结果后,Callable 会自动调用回调任务
界说 HystrixObservableCommand
[code]public class CommandObservable extends HystrixObservabCommand {  private String name;  private RestTemplate restTemplate;  public CommandObservable(String nane, RestTemplate restTemplate) {        super(HystrixConmandGroupKey.Factory.asKey("ExampleGroup"));    this.nane = name;    this.restTemplate = restTemplate;  }  //基于观察者模式的请求发布  @Override  protected Observable construct () {    return Observable.create(new Observable.OnSubscribe() {      @Override      public void call(Subscriber




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4