服务降级
Ⅰ、服务降级之Hystrix
1、Hystrix 介绍
-
Hystrix产生原因
- 因为分布式架构互相的服务调用,某些服务可能会出现网络超时、服务中断等问题而导致级联故障从而导致服务雪崩。
-
Hystrix(断路器)
- 用于处理分布式系统的延迟和容错的机制,保证在某个服务出问题的情况下,不会导致整体服务的失败,级联故障,提供分布式系统的弹性
- 断路器像一个开关,当单元故障后,通过故障监控,向调用方返回一个符合预期、可处理的备选响应,而不是长时间的等待或者抛出不可控制的异常,避免了整体服务的故障蔓延,乃至雪崩
-
Hystrix功能
-
服务降级
-
服务熔断@HystrixProperty标签配置熔断和恢复策略
-
实时监控 @EnableHystrixDashboard开启图形监控
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId> <version>1.4.7.RELEASE</version> </dependency>
-
限流
-
。。。
-
-
官网链接(停更) https://github.com/Netflix/Hystrix
2、Hystrix入门
-
Hystrix重要概念
- 服务降级(fallback):程序异常、超时、服务熔断、线程池打满等会导致服务降级
- 服务熔断(break):最大访问量之后,直接拒绝访问,调用降级策略返回友好提示。 服务降级 -> 熔断 -> 恢复
- 服务限流():高并发操作
-
Hystrix配置(可以配置在消费者也可以配置在生产者)
- pom(netflix 版本)
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> <version>2.2.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> <version>2.2.5.RELEASE</version> </dependency>
- yml
server: port: 8086 spring: application: name: eureka-client-hystrix eureka: instance: instance-id: hystrix8086 #访问路径可以显示IP prefer-ip-address: true #Eureka客户端向服务端发送心跳的时间间隔 单位秒(默认30) lease-renewal-interval-in-seconds: 1 #Eureka服务端在收到最后一次心跳后的等待时间上限,单位秒(默认90),超时剔除服务 lease-expiration-duration-in-seconds: 2 client: fetch-registry: true # false表示自己就是注册中心。我的职责就是维护服务实例,并不需要去检索服务 register-with-eureka: true # false表示自己不需要向注册中心注册自己 service-url: defaultZone: http://localhost:7003/eureka/ # 设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址(单机版) #defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/ # 集群版
- 业务配置
@Service public class HystrixService { public String testok(Integer id) { return "线程池: " + Thread.currentThread().getName() + " id :" + id + "😄"; } //服务降级、熔断的注解 @HystrixCommand(fallbackMethod = "testouthandle", commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000") }) public String testout(Integer id) { try { TimeUnit.SECONDS.sleep(5); } catch (Exception e) { e.printStackTrace(); } return "超时线程池: " + Thread.currentThread().getName() + " id :" + id + "😂"; } public String testouthandle(Integer id) { { return "超时线程池: " + Thread.currentThread().getName() + " id :" + id + "🐶; } } }
- main application
@SpringBootApplication @EnableEurekaClient @EnableCircuitBreaker public class HystrixApplication { public static void main(String[] args) { SpringApplication.run(HystrixApplication.class, args); } }
- 测试controller
@RestController public class HystrixController { @Autowired HystrixService hystrixService; @RequestMapping("/hystrix/testok/{id}") public String testok(@PathVariable Integer id) {return hystrixService.testok(id);} //运行结果:超时线程池: HystrixTimer-1 id :21🐶 @RequestMapping("/hystrix/testout/{id}") public String testout(@PathVariable Integer id) {return hystrixService.testout(id);} }