天天看点

spring clound hystrix使用总结

一、雪崩效应

在微服务架构中,通常会有多个服务层调用。如果某个服务不可用,导致级联故障,最终使整个系统不可用,这种现象就叫雪崩效应。例如A服务调用B服务,B服务调用C服务。当B服务调用C服务的时候由于某种原因调用失败,B服务就会一直重试,同步等待会造成资源耗尽,结果导致A服务B服务C服务都不可用,这种情况是非常可怕的!

二、spring cloud hystrix

spring cloud hystrix就是spring cloud提供的防雪崩的利器,它是基于netfix hystrix实现的,提供了服务降级、依赖隔离、服务熔断、监控(hystrix dashboard)等强大的功能,来防止雪崩效应。

三、服务降级

注意:服务降级是区分业务的。即优先保证核心业务,非核心业务不可用或者弱可用。

1.hystrix结合resttemplat实现服务降级

(1)添加依赖

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

(2)启动类上添加注解

@EnableCircuitBreaker
也可以使用@SpringCloudApplication,因为该注解包含了@SpringBootApplication、@EnableDiscoveryClient、@EnableCircuitBreaker
           

(3)在需要服务降级的方法上添加@HystrixCommand(fallbackMethod = “回退方法名”)

@GetMapping("/msg")
@HystrixCommand(fallbackMethod = "fallback")
public String msg(){
		//此处只是为了演示服务降级,所以直接用restTemplate的url硬编码的方式,正式的服务调用可以feign
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate.getForObject("http://localhost:8091/product/msg", String.class);
    }

//回退方法
public String fallback(){
        return "网络开小差了,请稍后再试!";
    }
           

注意:当controller中需要服务降级的方法很多的时候可以写一个默认的(通用的)回退方法。需要在controller类上面添加@DefaultProperties(defaultFallback = “回退方法名”)注解,然后需要服务降级的方法上只用添加@HystrixCommand注解即可不用指定fallback属性,当服务调用失败的时候就会走默认的回退方法。如果某个方法需要指定特殊的服务降级策略还是使用上面的方法即可。

2.hystrix结合feign使用(当一个controller类中的所有方法都需要服务降级的时候,使用上面的方法就会出现很多的fallback方法,并且和主业务方法耦合太高,所以和feign结合之后,可以将主业务方法和fallback方法分离,降低耦合)

(1)服务调用方添加依赖

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

(2)启动类上添加注解

@EnableCircuitBreaker
也可以使用@SpringCloudApplication,因为该注解包含了@SpringBootApplication、@EnableDiscoveryClient、@EnableCircuitBreaker
           

(3)在application.yml配置文件中添加配置

feign:
  hystrix:
    enabled: true
           

(4)在服务调用方(如果你将使用feign的接口定义在了公共模块中,就在公共模块中)定一个类实现fallbackFactory接口泛型中写的就是定义的feign接口类型

//DeptClientService是我定义的feign接口类型
//这样就可以实现主业务方法和fallback方法进行解耦
@Component // 不要忘记添加
public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService>
{
	@Override
	public DeptClientService create(Throwable throwable)
	{
		return new DeptClientService() {
			@Override
			public string get(long id)
			{
				return "网络开小差了,请稍后再试!";
			}

			@Override
			public string list()
			{
				return "定义自己具体服务降级的处理方法";
			}

			@Override
			public string add(Dept dept)
			{
				return "定义自己具体服务降级的处理方法";
			}
		};
	}
}
           

(5)然后在feign接口上的@FeignClient注解中添加fallbackFactory属性指定刚才实现了fallbackFactory接口的类

@FeignClient(value = "服务提供方的服务名",fallbackFactory=DeptClientServiceFallbackFactory.class)
           

(6)这样服务调用方就可以不用在需要降级的方法上添加@HystrixCommand注解了

4.服务降级中的超时设置(可以在HystrixCommandProperties类中找到该属性,默认超时时间是一秒)

@HystrixCommand(commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "2000")},fallbackMethod = "fallback")
           

四、依赖隔离

hystrix的依赖隔离类似于docker的舱壁模式,docker通过舱壁模式实现进程隔离,使得容器之间互不影响。而hystrix通过该模式实现的是线程池的隔离,会为每个hystrixCommand创建一个独立的线程池,这样就算某个在hystrixCommand包装下的依赖服务出现延迟过高的情况下,也只是对该依赖的服务的调用产生影响,并不会影响其他服务。使用了hystrixCommand来将某个函数包装成hystrix命令时,hystrix就会为这个函数自动实现了依赖隔离。所以依赖隔离服务降级在使用的时候都是一体化实现的。

五、服务熔断

(1)服务熔断

当某个服务单元发生故障,通过断路器的故障监控,直接切断原来的主逻辑调用。在微服务和分布式系统中服务容错是必须要考虑的,通常有两种模式。一种是重试机制,对于预期的短暂的故障可以使用重试机制解决,对于需要更长时间修复的故障,一直重试是没有意义的,这时候就需要用到断路器模式。断路器模式是将受保护的服务封装在一个可以监控故障的断路器对象中,当故障达到一定的值,断路器将会熔断,断路器对象直接返回错误。

(2)断路器状态机

spring clound hystrix使用总结

断路器状态机有三种状态,打开(open)、关闭(closed)、半打开状态(half open)。closed是熔断器关闭状态,当调用服务失败的次数达到一定的比例,熔断器就会打开。open是熔断器打开状态,此时对服务调用都直接返回错误。设置了一个时钟选项,当达到这个时间之后,断路器会切换到半熔断状态(half open),此时允许定量的请求,如果都调用成功或者一定的比例则认为恢复了,就会关闭熔断器。否则就认为还没好,又回到断路器打开状态。此时时钟选项清零又开始重新计时。

(3)服务熔断的使用,直接在@hystrixCommand注解中添加属性即可

@HystrixCommand(commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled",value = "true"),//设置熔断器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),//睡眠时间窗口内的最小请求数
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"),//睡眠时间窗口
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60")//判断熔断器打开或关闭的错误百分比
           

六、将上面的超时和服务熔断设置的属性写在配置文件中

上面的服务超时和熔断的设置是直接写在@hystrixCommand中的也可以将这些属性的设置写在配置文件中,虽然不用在@hystrixCommand上添加这些属性了,但是这个注解一定要添加,否则,不会生效。

hystrix:
  command:
    default: #default是全局设置默认的
      #超时时间
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 3000
      #设置熔断
      circuitBreaker:
        enabled: true
        requestVolumeThreshold: 10
        sleepWindowInMilliseconds: 10000
        errorThresholdPercentage: 60
    msg:#为某个方法单独设置,command的key默认为这个方法的方法名。列如这里的msg就表示为msg()这个方法单独设置的
      #超时时间
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 1000
      #设置熔断
      circuitBreaker:
        enabled: true
        requestVolumeThreshold: 10
        sleepWindowInMilliseconds: 10000
        errorThresholdPercentage: 60
           

七、监控(hystrixdashboard)

(1)添加依赖

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

(2)启动类上添加注解

@EnableHystrixDashboard
           

(3)配置文件中进行配置

#hystrix dashboard熔断监控的配置
management:
  endpoints:
    web:
      exposure:
        include: '*'
           

(4)监控页面的地址(写上自己的ip和端口号即可)

http://localhost:8090/hystrix

注意:因为spring Boot 2.0.x以后的actuator只暴露了info和health2个端点,这里我们把所有端点开放,include: '*'代表开放所有端点.

继续阅读