javascript
Spring Cloud【Finchley】-08使用Hystrix实现容错
文章目录
- 概述
- 实现容错主要方式
- Hystrix简介
- 通用方式整合Hystrix
- Step1 新建子module
- Step2 pom增加spring-cloud-starter-netflix-hystrix依赖
- Step3 启动类增加@EnableCircuitBreaker或者@EnableHystrix注解
- Step4 控制层增加注解即容错方法
- Step5 测试
- 代码
概述
前面的几篇博文,我们接触到了Eureka实现服务的注册于发现、Ribbon实现客户端负载均衡、Feign实现声明式的API调用,谈到微服务,容错也是不得不提的话题之一。
Soring Cloud 集成了Hystrix来提供容错的能力,从而实现微服务的容错。
实现容错主要方式
假设服务提供者的响应很慢,那么消费者的请求将会被强制等待,直到响应或者超时。 在高负载的情况下,很有可能发生的情况是,当依赖的服务不可用,自身的服务也被拖垮,这就是雪崩效应,当服务提供者不可用导致消费者不可用,并将不可用逐渐放大的过程。
容错的主要手段:
为网络请求设置超时: 通常情况下一次远程调用对应一个线程,如果响应太慢,这个线程就得不到释放,而线程占用的资源当然也不会被释放,当高并发或者未处理完的线程越来越多,资源终将被耗尽。
使用断路器模式:如果有对某个微服务的请求存在大量超时,禁止访问该微服务,防止雪崩。 当该微服务可用,断路器可以自动诊断是否已经恢复,恢复访问请求,从而实现微服务的自我修复
从而提升应用的高可用性。
Hystrix简介
https://github.com/netflix/hystrix
Hystrix是一个实现了超时机制和断路器模式的工具类库, 是由Netfix开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提升系统可用性与容错性。
机制:
当Hystrix Command请求后端服务失败数量超过一定比例(默认50%), 断路器会切换到开路状态(Open).这时所有请求会直接失败而不会发送到后端服务.
断路器保持在开路状态一段时间后(默认5秒), 自动切换到半开路状态(HALF-OPEN). 这时会判断下一次请求的返回情况, 如果请求成功, 断路器切回闭路状态(CLOSED), 否则重新切换到开路状态(OPEN).
Hystrix的断路器就像我们家庭电路中的保险丝, 一旦后端服务不可用, 断路器会直接切断请求链, 避免发送大量无效请求影响系统吞吐量,并且断路器有自我检测并恢复的能力.
Hystrix主要通过以下几点实现延迟和容错:
通用方式整合Hystrix
Spring Cloud官方指导:https://cloud.spring.io/spring-cloud-static/Finchley.SR2/single/spring-cloud.html#_circuit_breaker_hystrix_clients
Step1 新建子module
因为熔断是发生在调用方即消费者,所以我们copy个消费者的工程
父工程microservice-spring-cloud右键新建Maven Module 命名为:micorservice-consumer-movie-ribbon-hystrix ,为了简单我们把micorservice-consumer-movie-ribbon的内容copy到该子模块,修改下application.yml中的spring.application.name即可。
Step2 pom增加spring-cloud-starter-netflix-hystrix依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>Step3 启动类增加@EnableCircuitBreaker或者@EnableHystrix注解
package com.artisan.micorservice;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate;@SpringBootApplication @EnableCircuitBreaker public class MicorserviceMovieRibbonHystrix {@Bean@LoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();}public static void main(String[] args) {SpringApplication.run(MicorserviceMovieRibbonHystrix.class, args);} }Step4 控制层增加注解即容错方法
package com.artisan.micorservice.controller;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate;import com.artisan.micorservice.model.User; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;import lombok.extern.slf4j.Slf4j;@RestController public class MovieController {@Autowiredprivate RestTemplate restTemplate;@AutowiredLoadBalancerClient loadBalancerClient;@HystrixCommand(fallbackMethod = "findByIdDefault")@GetMapping("/movie/{id}")public User findById(@PathVariable Long id) {return this.restTemplate.getForObject("http://microservice-provider-user/user/" + id, User.class);}/*** * @param id* @return* @desc 当请求失败、超时、被拒绝,或当断路器打开时,执行的逻辑*/public User findByIdDefault(Long id) {User user = new User();user.setId(id);user.setUsername("默认用户");return user;}}从上述Controller层的方法中,可以看到我们在findById方法上增加了注解 @HystrixCommand(fallbackMethod = “findByIdDefault”),并通过fallbackMethod 属性指定了当请求失败、超时、被拒绝,或当断路器打开时,执行的方法findByIdDefault.
HystrixCommand注解还可以使用注解HystrixProperty的commandProperties属性来配置HystrixCommand
比如
@HystrixCommand(fallbackMethod = "findByIdDefault",commandProperties= {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="5000"),@HystrixProperty(name="metrics.rollingStats.timeInMilliseconds",value="10000")},threadPoolProperties= {@HystrixProperty(name="coreSize",value="1"),@HystrixProperty(name="maxQueueSize",value="10")})@GetMapping("/movie/{id}")public User findById(@PathVariable Long id) {return this.restTemplate.getForObject("http://microservice-provider-user/user/" + id, User.class);}可配置的属性见官网: https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica#configuration
Step5 测试
访问http://localhost:8761/ 确认下服务已经注册成功。
访问: http://localhost:7902/movie/2 ,返回
{"id":2,"username":"artisan2","name":"小工匠二","age":20,"balance":200.00}停止 micorservice-provider-user,服务提供者 ,注册中心上已经没有该服务了。
访问http://localhost:7902/movie/2 ,可访问多次,均返回
{"id":2,"username":"默认用户","name":null,"age":null,"balance":null}已经走到了我们自定义的方法中。
再次启动 micorservice-provider-user,服务提供者
访问http://localhost:7902/movie/2
{"id":2,"username":"artisan2","name":"小工匠二","age":20,"balance":200.00}服务已经恢复。
当请求失败、被拒绝、超时或者断路器打开时都会进入到回退的方法,当进入回退方法并不意味着断路器已经被打开。
代码
https://github.com/yangshangwei/SpringCloudMaster/tree/master/micorservice-consumer-movie-ribbon-hystrix
总结
以上是生活随笔为你收集整理的Spring Cloud【Finchley】-08使用Hystrix实现容错的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: Spring Cloud【Finchle
- 下一篇: Spring Cloud【Finchle