[SpringCloud系列010] SpringCloud之Hystrix 傷城~ 2024-02-18 20:47 11阅读 0赞 **Hystrix 介绍 详解,服务降级,熔断,限流** ![这里写图片描述][70] 服务雪崩效应–级联效应 \*\*服务雪崩效应:\*\*因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过 程,就叫服务雪崩效应 导致雪崩效应的最根本原因是: 大量请求线程同步等待造成的资源耗尽 **解决方案** 1. 超时机制 2. 服务限流 3. 服务熔断 4. 服务降级 在整个SpringCloud构建微服务的体系中,有一个提供超时机制,限流,熔断,降级最全面 的实现:Hystrix(豪猪) 翻译过来表示:自身带刺,有自我保护的意思,外国人起名字还是 很有意思滴。当然Hystrix并不是Spring的,而是NetFlix公司开源的。那么Spring只是把它 拿过来,在他的基础上面做了一些封装,然后加入到了SpringCloud中,实现高可用的分布 式微服务架构 **引入hystrix** ![这里写图片描述][70 1] @HystrixCommond @EnableCircuitBreaker 那么Hystrix是怎么做到降级的呢? 他通过一种叫做“命令模式”的方式,继承(HystrixCommand类)来包裹具体的服务调用 逻辑(run方法), 并在命令模式中添加了服务调用失败后的降级逻辑(getFallback),见 (OrderServiceCommand类) ![这里写图片描述][70 2] **降级(报错,超时)** fallback fallbackMethod,返回静态的信息.备用接口/缓存/mock数据 **熔断fusing** 重试次数,自动恢复时间,可以再yml中配置的 测试报错和正常的情况,我们可以看到当报错达到一定阈值时,会自动熔断,阈值可以配 置,如下: 一个rolling window内最小的请求数。如果设为20,那么当一个rolling window的时间内(比如说1个rolling window是10秒)收到19个请求,即使19个请求都失败,也不会触发 circuit break。默认20 hystrix.command.default.circuitBreaker.requestVolumeThreshold \# 触发短路的时间值,当该值设为5000时,则当触发circuit break后的5000毫秒内都会拒 绝request,也就是5000毫秒后才会关闭circuit。默认5000 hystrix.command.default.circuitBreaker.sleepWindowInMilliseconds **限流** 配置线程组 线程池,队列 默认是10个线程 fallback的数据会统计在Metrics中,就是配置熔断的时候使用 用JMeter做压测 **@HystrixCommand(fallbackMethod = “findByIdFallback”)** @RestController public class OrderController { private static final Logger logger = LoggerFactory.getLogger(OrderController.class); @Autowired private RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "findByIdFallback") @GetMapping("/user/{id}") public User findById(@PathVariable Long id) { logger.info("================请求用户中心接口=============="); return this.restTemplate.getForObject( "http://microservice-provider-user/" + id, User.class); } public User findByIdFallback(Long id) { User user = new User(); user.setId(-1L); user.setName("默认用户"); return user; } } @EnableDiscoveryClient @SpringBootApplication @EnableCircuitBreaker public class ConsumerOrderApplication { @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(ConsumerOrderApplication.class, args); } } **降级配置** server: port: 8010 spring: application: name: microservice-consumer-order eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ instance: prefer-ip-address: true hystrix: command: default: circuitBreaker: requestVolumeThreshold: 1 execution: isolation: thread: timeoutInMilliseconds: 4000 **UserController** @RestController public class UserController { private final Logger logger = Logger.getLogger(getClass()); @Autowired private UserRepository userRepository; @Autowired private Registration registration; @GetMapping("/{id}") public User findById(@PathVariable Long id) throws Exception { logger.info("用户中心接口:查询用户"+ id +"信息"); /*//测试超时触发降级 int sleepTime = new Random().nextInt(2000); logger.info("sleepTime:" + sleepTime); Thread.sleep(sleepTime); */ /*//测试熔断,传入不存在的用户id模拟异常情况 if (id == 10) { throw new NullPointerException(); }*/ //测试限流,线程资源隔离,模拟系统执行速度很慢的情况 // Thread.sleep(3000); User findOne = userRepository.findOne(id); return findOne; } @GetMapping("/getIpAndPort") public String findById() { return registration.getHost() + ":" + registration.getPort(); } } **熔断配置** server: port: 8010 spring: application: name: microservice-consumer-order eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ instance: prefer-ip-address: true hystrix: command: default: circuitBreaker: requestVolumeThreshold: 3 #次数 sleepWindowInMilliseconds: 10000 #时间 **限流,超时模拟** 测试限流,线程资源隔离,模拟系统执行速度很慢的情况 Thread.sleep(3000); server: port: 8010 spring: application: name: microservice-consumer-order eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ instance: prefer-ip-address: true hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 20000 **配置线程池线程组** **参数queueSizeRejectionThreshold 和maxQueueSize 。queueSizeRejectionThreshold默认值是5,允许在队列中的等待的任务数量,超过线程组配置大小的请求直接降级,优先输出,返回结果** @RestController public class OrderController { private static final Logger logger=LoggerFactory.getLogger(OrderController.class); @Autowired private RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "findByIdFallback", groupKey = "orderUserGroup", threadPoolKey = "orderUserIdThreadPool", threadPoolProperties = { @HystrixProperty(name = "coreSize", value = "2"), @HystrixProperty(name ="queueSizeRejectionThreshold", value = "1") }) @GetMapping("/user/{id}") public User findById(@PathVariable Long id) { logger.info("=============="); "http://microservice-provider-user/" + id, User.class); } public User findByIdFallback(Long id) { User user = new User(); user.setId(-1L); user.setName("默认用户"); return user; } } **引入依赖** <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> [70]: https://image.dandelioncloud.cn/pgy_files/images/2024/01/29/3efdd1ec23cc4691ab68554d5e2298e6.png [70 1]: https://image.dandelioncloud.cn/pgy_files/images/2024/01/29/870324a8e3bb4149882dba686c5d2a8a.png [70 2]: https://image.dandelioncloud.cn/pgy_files/images/2024/01/29/b435ba2dc999488881e46c70c9e15942.png
还没有评论,来说两句吧...