微服务:Eureka,Ribbon,Hystrix( 九 )

  • 限制远程接口调用速率、限制 MQ 的消费速率等 。
  •  
    Hystrix 简介Hystrix - defend your application 是由 Net?ix 开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性与容错性 。
    Hystrix 主要通过以下几点实现延迟和容错:
    • 包裹请求:使用 HystrixCommand 包裹对依赖的调用逻辑 。如页面静态化微服务方法使用 @HystrixCommand 添加 Hystrix 控制 。
    • 跳闸机制:当某服务的错误率超过一定的阈值时,Hystrix 可以跳闸,停止请求该服务一段时间 。
    • 资源隔离:Hystrix 为每个依赖都维护了一个小型的线程池 - 舱壁模式 。如果该线程池已满,发往该依赖的请求就被立即拒绝,而不是排队等待,从而加速失败判定 。
    • 监控:Hystrix 可以近乎实时地监控运行指标和配置的变化,例如成功、失败、超时、以及被拒绝的请求等 。
    • 回退机制:当请求失败、超时、被拒绝,或当断路器打开时,执行回退逻辑 。回退逻辑由开发人员自行提供,例如返回一个默认值 。
    • 自我修复:断路器打开一段时间后,会自动进入“半开”状态,从而探测服务是否可用;如果还是不可用,再次退回打开状态 。
     
    Hystrix 应用熔断处理目的:商品微服务长时间没有响应,服务消费者 --> 页面静态化微服务快速失败给用户提示 。
    引入依赖:服务消费者工程(静态化微服务)中引入Hystrix依赖坐标(也可以添加在父工程中)
    <!-- 熔断器 Hystrix --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency>开启熔断:服务消费者工程(静态化微服务)的启动类中添加熔断器开启注解 @EnableCircuitBreaker 。
    @SpringBootApplication@EnableDiscoveryClient@EnableCircuitBreaker // 启用熔断服务public class PageApplication {public static void main(String[] args) {SpringApplication.run(PageApplication.class,args);}// 向容器中注入一个 RestTemplate,封装了 HttpClient@Bean@LoadBalanced // 启动请求的 Ribbon 负载均衡public RestTemplate restTemplate(){return new RestTemplate();}}定义服务降级处理方法:业务方法上使用 @HystrixCommand 的 fallbackMethod 属性关联到服务降级处理方法 。
    @RestController@RequestMapping("/page")public class PageController {?@AutowiredRestTemplate restTemplate;?...?/*** 模拟服务超时,熔断处理* 针对熔断处理,Hystrix 默认维护一个线程池,默认大小为 10 。*/@HystrixCommand(//只有是在 @HystrixCommand 中定义了 threadPoolKey,就意味着开启了舱壁模式(线程隔离),该方法就会自己维护一个线程池 。// 默认所有的请求共同维护一个线程池,实际开发:每个方法维护一个线程池threadPoolKey = "getProductServerPort2",// 每一个属性对应的都是一个 HystrixPropertythreadPoolProperties = {// 并发线程数@HystrixProperty(name = "coreSize", value = https://www.isolves.com/it/cxkf/jiagou/2021-03-03/"1"),// 默认线程队列值是 -1,默认不开启@HystrixProperty(name = "maxQueueSize", value = "20")},// 超时时间的设置commandProperties = {// 设置请求的超时时间,一旦请求超过此时间那么都按照超时处理,默认超时时间是 1s@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")})@GetMapping("/loadProductServicePort2")public String getProductServerPort2() {return restTemplate.getForObject("http://lagou-service-product/service/port", String.class);}?}商品微服务模拟超时操作:
    @RestController@RequestMapping("/service")public class ServiceInfoController {?@Value("${server.port}")private String port;?@GetMapping("/port")public String getPort(){try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}return port;}?}使用 Postman 测试:
    GET http://localhost:9100/page/loadProductServicePort2
    测试返回超时错误信息:getProductServerPort2 timed-out and fallback failed. 。
    因为没有降级处理,所以只得到 500 超时错误信息 。
    降级处理配置 @HystrixCommand 注解,定义降级处理方法:
    @RestController@RequestMapping("/page")public class PageController {?@AutowiredRestTemplate restTemplate;...?/*** 服务降级演示:是在服务熔断之后的兜底操作*/@HystrixCommand(// 超时时间的设置commandProperties = {// 设置请求的超时时间,一旦请求超过此时间那么都按照超时处理,默认超时时间是 1s@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = https://www.isolves.com/it/cxkf/jiagou/2021-03-03/"2000"),// 统计窗口时间的设置@HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds",value = "8000"),// 统计窗口内的最小请求数@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "2"),// 统计窗口内错误请求阈值的设置50%@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "50"),// 自我修复的活动窗口时间@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "3000")},// 设置回退方法fallbackMethod = "getProductServerPortFallBack")@GetMapping("/loadProductServicePort3")public String getProductServerPort3() {return restTemplate.getForObject("http://lagou-service-product/service/port", String.class);}?/*** 定义回退方法,当请求出发熔断后执行,补救措施* 注意:*1.方法形参和原方法保持一致*2.方法的返回值与原方法保持一致*/public String getProductServerPortFallBack(){// 兜底数据return "-1";}?}


    推荐阅读