目录
一、 Hystrix 简介
1 什么是灾难性雪崩效应
2 什么是 Hystrix
二、 服务降级
1 修改 application service 代码
2 application client POM 依赖
3 application client 容错处理代码
4 application client 配置文件 application.yml
5 application client 启动类
三、 服务熔断
1 application client POM 依赖
2 application client 容错处理代码
3 application client 配置文件 application.yml
4 application client 启动类
四、 请求缓存
1 修改 application service 代码
2 application client POM 依赖
3 application client 容错处理代码
4 application client 配置文件 application.yml
5 application client 启动类
五、 Openfeign 的雪崩处理
1 服务降级
1.1 POM 依赖
1.2 application client 接口
1.3 application client 接口实现
1.4 application client 配置文件 application.yml
1.5 applicaiton client 启动类
2 服务熔断
六、 可视化的数据监控 Hystrix-dashboard
1 POM 依赖
2 配置文件 application.yml
3 启动类
4 访问 Hystrix 监控数据
@RestControllerpublic class ServiceController {@GetMappingpublic Object first(){try {// 用于模拟远程服务调用延时。Thread. sleep ( 2000 );} catch (InterruptedException e) {e.printStackTrace();}return "测试 Spring Cloud Netflix Ribbon 开发服务提供者" ;}}
< dependency >< groupId >org.springframework.cloud groupId >< artifactId >spring-cloud-starter-netflix-hystrix artifactId >dependency >
@Servicepublic class ClientServiceImpl implements ClientService {@Autowiredprivate LoadBalancerClientloadBalancerClient ;/*** @HystrixCommand - 开启 Hystrix 容错处理的注解。代表当前方法如果出现服务调用问题,使用 Hystrix 容错处理逻辑来处理 *属性 fallbackMethod - 如果当前方法调用服务,远程服务出现问题的时候,调用本地的哪个方法得到托底数据。*/@HystrixCommand(fallbackMethod = "downgradeFallback" )@Overridepublic String first() {ServiceInstance si = this . loadBalancerClient .choose( "application-service" );StringBuilder sb = new StringBuilder();sb.append( "http://" ).append(si.getHost()).append( ":" ).append(si.getPort()).append( "/" );System. out .println( "本次访问的 service 是: " + sb.toString());RestTemplate rt = new RestTemplate();ParameterizedTypeReferencetype = new ParameterizedTypeReference(){}; ResponseEntityresponse = rt.exchange(sb.toString(), HttpMethod. GET , null , type);Stringresult = response.getBody();returnresult;}// 本地容错方法,只有远程服务调用过程出现问题的时候,才会调用此方法,获取托底数据。保证服务完整性。private String downgradeFallback(){return "服务降级方法返回托底数据" ;}}
@Servicepublic class ClientServiceImplimplements ClientService {@Autowiredprivate LoadBalancerClientloadBalancerClient ;/*** @HystrixCommand - 开启 Hystrix 容错处理的注解。代表当前方法如果出现服务调用问题,使用 Hystrix 容错处理逻辑来处理*属性 fallbackMethod - 如果当前方法调用服务,远程服务出现问题的时候,调用本地的哪个方法得到托底数据。*/@HystrixCommand (fallbackMethod = "downgradeFallback" ,commandProperties = {// 默认 20 个;10s 内请求数大于 20 个时就启动熔断器,当请求符合熔断条 件时将触发 fallback 逻辑@HystrixProperty(name =HystrixPropertiesManager. CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD , value = "10" ),// 请求错误率大于 50%时就熔断,然后 for 循环发起请求,当请求符合熔断条件时将触发@HystrixProperty(name =HystrixPropertiesManager. CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE , value = "50" ),// 默认 5 秒;熔断多少秒后去尝试请求@HystrixProperty(name =HystrixPropertiesManager. CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS , value ="5000" )})@Overridepublic String first() {ServiceInstance si =this . loadBalancerClient .choose( "application-service" );StringBuilder sb = new StringBuilder();sb.append( "http://" ).append(si.getHost()).append( ":" ).append(si.getPort()).append( "/" );System. out .println( "本次访问的 service 是: " + sb.toString());RestTemplate rt = new RestTemplate();ParameterizedTypeReferencetype = new ParameterizedTypeReference() { };ResponseEntityresponse = rt.exchange(sb.toString(), HttpMethod. GET , null , type);Stringresult = response.getBody();returnresult;}// 本地容错方法,只有远程服务调用过程出现问题的时候,才会调用此方法,获取托底数据。保证服务完整性。private String downgradeFallback(){return "服务降级方法返回托底数据" ;}
@RestControllerpublic class ServiceController {@PostMapping ( "/testPost" )public Object testPost(){System. out .println( "testPost method run" );return "写操作返回" ;}@GetMapping ( "/testGet" )public Object testGet(){System. out .println( "testGet method run" );return "读操作返回" ;}@GetMappingpublic Object first(){System. out .println( "run" );try {// 用于模拟远程服务调用延时。 Thread. sleep ( 2000 );} catch (InterruptedException e) {e.printStackTrace();}return "测试 Spring Cloud Netflix Ribbon 开发服务提供者" ;}}
/***在类上,增加@CacheConfig 注解,用来描述当前类型可能使用 cache 缓存。*如果使用缓存,则缓存数据的 key 的前缀是 cacheNames。*cacheNames 是用来定义一个缓存集的前缀命名的,相当于分组。*/@CacheConfig(cacheNames = "test.hystrix.caches" )@Servicepublic class ClientServiceImpl implements ClientService {@Autowiredprivate LoadBalancerClient loadBalancerClient ;/*** @HystrixCommand - 开启 Hystrix 容错处理的注解。代表当前方法如果出现服务调用问题,使用 Hystrix 容错处理逻辑来处理*属性 fallbackMethod - 如果当前方法调用服务,远程服务出现问题的时候,调用本地的哪个方法得到托底数据。*/@HystrixCommand (fallbackMethod = "downgradeFallback" ,commandProperties = {// 默认 20 个;10s 内请求数大于 20 个时就启动熔断器,当请求符合熔断条件时将触发 fallback 逻辑 @HystrixProperty (name =HystrixPropertiesManager. CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD , value = "10" ),// 请求错误率大于 50%时就熔断,然后 for 循环发起请求,当请求符合熔断条件时将触发@HystrixProperty (name =HystrixPropertiesManager. CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE , value = "50" ),// 默认 5 秒;熔断多少秒后去尝试请求@HystrixProperty (name =HystrixPropertiesManager. CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS ,value = "5000" )})@Overridepublic String first() {ServiceInstance si = this . loadBalancerClient .choose( "application-service" );StringBuilder sb = new StringBuilder();sb.append( "http://" ).append(si.getHost()).append( ":" ).append(si.getPort()).append( "/" );System. out .println( "本次访问的 service 是: " + sb.toString());RestTemplate rt = new RestTemplate();ParameterizedTypeReferencetype = new ParameterizedTypeReference() {}; ResponseEntityresponse = rt.exchange(sb.toString(), HttpMethod. GET , null , type);Stringresult = response.getBody();return result;}/***@Cacheable - 将当期方法的返回值缓存到 cache 中。*只要方法增加了@Cacheable 注解,每次调用当前方法的时候,spring cloud都会先访问 cache 获取数据,*如果 cache 中没有数据,则访问远程服务获取数据。远程服务返回数据,先保存在 cache 中,再返回给客户端。*如果 cache 中有数据,则直接返回 cache 中的数据,不会访问远程服务。 *请求缓存会有缓存数据不一致的可能。缓存数据过期、失效、脏数据等情况。*一旦使用了请求缓存来处理幂等性请求操作。则在非幂等性请求操作中必须管理缓存。避免缓存数据的错误。* @return*/@Override@Cacheable( "myCache" )public String testGet() {ServiceInstance si = this . loadBalancerClient .choose( "application-service" );StringBuilder sb = new StringBuilder();sb.append( "http://" ).append(si.getHost()).append( ":" ).append(si.getPort()).append( "/testGet" );System. out .println( "本次访问的 service 是: " + sb.toString());RestTemplate rt = new RestTemplate();ParameterizedTypeReferencetype = new ParameterizedTypeReference() { }; ResponseEntityresponse = rt.exchange(sb.toString(), HttpMethod. GET , null , type);String result = response.getBody();returnresult;}/***@CacheEvict - 管理缓存。根据参数 key 删除缓存中对应的缓存数据。*@return*/@Override@CacheEvict( "myCache" )public String testPost() {ServiceInstance si = this . loadBalancerClient .choose( "application-service" );StringBuilder sb = new StringBuilder();sb.append( "http://" ).append(si.getHost()).append( ":" ).append(si.getPort()).append( "/testPost" );System. out .println( "本次访问的 service 是: " + sb.toString()); RestTemplate rt = new RestTemplate();ParameterizedTypeReferencetype = new ParameterizedTypeReference() { };ResponseEntityresponse = rt.exchange(sb.toString(), HttpMethod. POST , null , type);String result = response.getBody();return result;}// 本地容错方法,只有远程服务调用过程出现问题的时候,才会调用此方法,获取托底数据。保证服务完整性。private String downgradeFallback(){return "服务降级方法返回托底数据" ;}}
/*** 注解属性 fallback - 当前接口远程调用服务发生问题时,使用哪一个对象中的对应方法用于实现容错逻辑。*Openfeign 技术中,容错处理是使用当前接口的实现类实现的。*实现类中的方法实现,就是对应的容错 fallback 处理逻辑。*/@FeignClient (name= "openfeign-service" , fallback =FirstClientServiceImpl. class )public interface FirstClientService extends FirstServiceAPI {}
/***当前类型的实例必须由 Spring 容器管理,需要使用@Component 注解描述。*每个实现方法对应远程服务调用的容错处理逻辑。*/ @Componentpublic class FirstClientServiceImpl implements FirstClientService {@Overridepublic ListtestFeign() {return Arrays. asList ( "Openfeign 返回托底数据" );}@Overridepublic User getMultiParams(Integer id, String name) {User user = new User();user.setId( 0 );user.setUsername( "托底数据" );user.setRemark( "getMultiParams" );return user;}@Overridepublic User postMultiParams(Integer id, String name) {User user = new User();user.setId( 0 );user.setUsername( "托底数据" );user.setRemark( "postMultiParams" );return user;}@Overridepublic User postObjectParam(User pojo) {User user = new User();user.setId( 0 );user.setUsername( "托底数据" );user.setRemark( "postObjectParam" );return user;}}
进入后的监控视图界面具体含义如下: