服务降级之Hystrix使用

一、什么是服务降级、服务熔断和限流?

  复杂的分布式体系结构中服务之间的依赖较多,进行服务调用时不可避免出现调用失败的情况,而且调用往往呈现链式调用,某一环节出现错误将会导致致命问题,产生可怕的“服务雪崩”效应,导致整个系统故障。为了解决上述这个问题,我们需要一定的手段来保证核心服务能够正常运行,因此需要临时丢弃或隔离这些出现问题的服务,这就是服务降级和熔断。要注意的是服务降针对的是非核心服务,有些服务是不能进行降级和熔断的,核心服务的熔断和降级意味着整体业务体系无法使用,比如购物车结算服务等。

  服务降级和服务熔断及限流是有区别的:

    1、降级体现在即使调用的服务出现问题时,任然向上级返回一个友好的提示(比如返回服务器忙,请稍后再试),不向上级抛出错误,不让上级等待。程序运行异常、超时、服务熔断触发服务降级、线程池满等情况都会导致服务降级。

    2、熔断类似于保险丝,体现在当达到最大访问负载后,直接跳闸拒绝服务,然后触发降级方法返回友好的提示。

    3、限流体现在控制访问并发量,严禁某一时间段内出现大量的访问。

  在考虑降级之前,需要进行整体的业务系统分析,确保哪些服务是可以降级的。超时不再等待,宕机要有兜底解决方案......整理一套降级方案。常见的服务降级方案:访问超时降级、频率超限降级、服务故障降级、人工预警降级等。

二、什么是Hystrix?

  Hystrix是一个用于处理分布式系统延迟和容错的开源库,它能保证在某一个服务出现问题的情况下,不会导致整体服务的联级故障,以提高分布式系统的弹性。Hystrix支持服务降级、服务熔断、实时监控、服务限流、隔离等功能,一般用于服务消费者模块中做降级(也可以用于服务提供者模块),但目前官网已停止更新,进入维护阶段。

三、Hystrix的使用

  1、修改Pom文件,引入jar包

<! --hystrix-->
<dependency>
  <groupId>org.springframework.cloud</ groupId>
  <artifactId>spring-cloud-starter-nftflix-hystrix</artifactId>
</dependency>

  2、业务方法上增加@HystrixCommand(fallbackMethod = "falltHandler")注解,表示如果使用该注解的方法报错了,就调用fallbackMethod 指定的兜底方法执行处理流程。

@HystrixCommand(fallbackMethod="falltHandler")
public string methodserver()
{
int age = 10/0; return "尝试调用微服务模块。。";
}
public string falltHandler()
{ return "服务器错误,请稍后再试!";
}

  3、业务方法上增加@HystrixCommand(fallbackMethod = "falltHandler",commandProperties = {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds" , value="3000")})注解,表示如果使用该注解的方法执行超过3秒中,就调用fallbackMethod 指定的兜底方法执行处理流程。

@HystrixCommand(fallbackMethod = "falltHandler",commandProperties = {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds" , value="3000")})
public string methodserver()
{
  //等待3秒中...
   return "尝试调用微服务模块。。";
}
public string falltHandler()
{
  return "对方服务器超时,请稍后再试!";
}

  4、如果需要feign等组件支持Hystrix,还需要完成一下两步

    a.主启动类上增加@EnableCircuitBreaker注解

    b.在application.yml配置文件中增加以下代码

feign:
   hystrix:
       enabled: true

 四、全局兜底方法配置

  以上代码的实现中,每个方法都对应一个兜底方法,这导致了代码膨胀,有时候很多方法可以公用一个默认兜底方法来进行处理,hystrix提供了一个注解@Defaultproperties(defaultFallback = “Global_FallbackMethod")来指定这个默认的兜底方法,该注解作用与类上。如果该类的方法上有指定的兜底方法则使用指定的兜底方法,否则使用这个默认的兜底方法。

@Restcontroller
@DefaultProperties(defaultFallback = "global_FallbackMethod")
public class Hvstirxcontroller { public string global_FallbackMethod()
{
return "全局兜底方法!";
}
}

  五、微服务接口降级处理

  按照前面说的,都在业务方法上增加兜底方法,进行降级处理,也一定会导致代码臃肿,与其在Controller层对所有方法设置降级,还不如在调用微服务的接口类中去统一处理。Feign结合hystrix(要注意开启结合功能,详见前面介绍的开启方法)提供了一种实现方式,实现步骤:

    1、新增一个类FallbackService实现微服务接口类,重写微服务接口中方法。

    2、在微服务接口类上增加注解@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX",fallback = FallbackService.class)。

  完成以上两步设置后,微服务接口方法将以FallbackService类中重写的方法作为它的兜底方法,当微服务接口方法调用出错时,就会执行对应的重写方法。

 六、断路器

  断路器是Hystrix实现服务熔断的一种机制,熔断机制是应对服务雪崩的一种保护,当调用链路出现问题时,会先进行服务降级,进而熔断该节点的调用,当检测到节点恢复正常后,再次恢复链路调用。在SpringCloud框架中熔断机制是通过Hystrix实现的,Hystrix会监控微服务的调用状况。断路器本身有三种状态,开启、关闭和半开状态。当断路器在开启状态不允许调用、在关闭状态允许调用、半开状态尝试调用,若调用成功后状态变成关闭状态,反正变成开启状态。

  Hystrix中@HystrixCommand注解提供了如下几个参数,用于配置断路器

@HystrixCommand(
fallbackMethod = "CircuitBreaker_fallback",
commandProperties =
{ @HystrixProperty(name = "circuitBreaker.enabled" , value = "true" ), @HlystrixProperty(name = "circuitBreaker.requestVolumeThreshold" ,value = "10"), @HystrixProperty(name = "circuitBreaker.sleepwindowInMi1liseconds" , value = "1000"),
@HlystrixProperty(name = "circuitBreaker.errorThresholdPercentage" , value = "60") })

  其中,fallbackMethod指定兜底方法,即当服务调用异常或断路器状态在开启(与circuitBreaker.enabled指定的状态概念不同)状态时调用的处理方法。circuitBreaker.enabled指定是否启用断路器功能,circuitBreaker.requestVolumeThreshold指定请求次数峰值(达到峰值后跳闸),circuitBreaker.sleepwindowInMiliseconds指定时间间隔(统计峰值和失败率的时间段),circuitBreaker.errorThresholdPercentage指定失败率(失败率达到后跳闸)。例子如下

//=====服务熔断
@HystrixCommand(fallbacknethod = "circuitBreaker_fallback" ,commandProperties = {
@HystrixProperty(name = "circuitBreaker.enabled" , value =“true"),
@HystrixProperty(name = "circuitBreaker.requestvolumeThreshold",value = "100"),
@HystrixProperty(name = "circuitBreaker.sleepwindowInNi1liseconds" ,value = "1000"),
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage" ,value = "60")
})
public string CircuitBreaker(@Pathvariable("id") Integer id)
{ if(id < 0) { throw new RuntimeException(”*id不能负数");
} return Thread.currentThread( ).getName( )+""\t"+"调用成功!";
}
public string circuitBreaker_fallback(@Pathvariable("id") Integer id) { return "id 不能负数,请稍后再试!";
}

  上述表示,在1秒钟内如果调用失败率达到60%或者请求达到峰值100次,则直接跳闸执行circuitBreaker_fallback方法。断路器在开启状态时,隔一段时间(默认5秒)会将状态转换为半开状态,后续请求会尝试调用链路,若成功则将断路器置为关闭状态,正常执行CircuitBreaker方法,否则继续将断路器状态变为开启状态,执行circuitBreaker_fallback方法。

  除了上述的基本配置功能外,Hystrix还提供了其他的配置项,请参考某大神的https://www.cnblogs.com/throwable/p/11961016.html,这里不在详述。

七、Hystrix服务监控仪表盘Dashboard

  Hystrix提供了实时的服务监控界面,Hystrix会持续第记录所有通过Hystrix发起的请求,并以报表和图形的形式展示给用户,SpringCloud整合了HystrixDashboard,把监控的内容转化成可视化界面。

  创建Hystrix服务监控程序的步骤:1创建模块,2POM引入jar包,3配置yml配置文件,4主启动类上增加@EnableHystrixDashboard注解,5被监控的服务配置依赖,6启动服务访问服务地址显示web可视化界面。

   1、监控服务模块需要引入dashboard的jar包

<dependency>
 <groupId>org.springframework.cloud</groupid>
 <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>

  2、被监控的服务模块需要引入actuator的jar包,而且要在主启动类上增加@EnablecircuitBreaker注解。

<! -- actuator监控信息模块-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

  注意:新版本springcloud的被监控服务模块需要在主启动类下增加如下代码,否则可能导致无法显示监控数据

/**
*此配置是为了服务监控而配置,与服务容错本身无关,springcloud升级后的坑
*ServLetRegistrationBean因为springboot的默认路径不是"/hbystcix.stream",*只要在自已的项目里配置上下面的servlet就可以了
*/
@Bean
public servletRegistrationBean getservlet() {
  HystrixMetricsstreamServlet streamServlet = new HystrixMetricsstreamServlet();
  ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamservlet);
registrationBean.setLoadonstartup(1); registrationBean.addurlMappings("/hystrix.stream" ); registrationBean.setName("HystrixMetricsstreamservlet");
return registrationBean;
}

  3、web可视化页面启动成功后,在地址栏输入要监控的微服务的地址,即可对该服务实现监控,界面如下

服务降级之Hystrix使用

  服务降级之Hystrix使用

  八、Hystrix工作流程图

服务降级之Hystrix使用

 

 

 

 

 

 

 

 

上一篇:springcloud组件梳理之hystrix


下一篇:微服务的远程调用