Spring Cloud 实战(二)使用hystrix有效处理服务雪崩

首先记录一下Hystrix的底层是如何实现的?今天想了一下其实也不难,整体逻辑就是利用Aop实现的。源码:在HystrixCommandAspect中,先看看切入点

@Pointcut("@annotation(com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand)")
    public void hystrixCommandAnnotationPointcut() {
    }
 @Pointcut("@annotation(com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser)")
    public void hystrixCollapserAnnotationPointcut() {
    }
    //设置了两个切点都是利用自定义注解切入的

然后接着执行methodsAnnotatedWithHystrixCommand方法

public Object methodsAnnotatedWithHystrixCommand(ProceedingJoinPoint joinPoint) throws Throwable {
	…代码省略…
	  Object result;
      if (!metaHolder.isObservable()) {
          result = CommandExecutor.execute(invokable, executionType, metaHolder);//当不可见,就会去执行fallbackMethod中的方法
      } else {
          result = this.executeObservable(invokable, executionType, metaHolder);
      }
      return result;
	…代码省略…
}

最后会执行到HystrixCommand

    public R execute() {
        try {
            return this.queue().get();//也就是这句代码取得了fallbackMethod返回的值
        } catch (Exception var2) {
            throw Exceptions.sneakyThrow(this.decomposeException(var2));
        }
    }

开篇

在分布式系统中,我们可能会有服务A调用服务B然后服务B再调用服务C的业务。那么如果服务C宕机了或者阻塞了,服务B同时也会阻塞,服务A也会阻塞。如果对此不做任务处理的话,那么服务ABC会全部宕机,这就是服务雪崩。

在这里插入图片描述
而hystrix的熔断、降级就是对付雪崩的有效处理方式。本篇就使用hystrix来处理这一问题…… 废话不多说,开始实战吧

Hystrix(服务降级、熔断)

在进行这一步的之前,先要将Spring Cloud搭建起来,如果还不知道如何搭建可以看看上一篇:
Spring Cloud 实战(一)以eureka作为服务注册中心

配置pom

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

2022年10月5日更新
由于spring2.x.x>=2.0.0已经去掉了org/springframework/boot/autoconfigure/web/ServerPropertiesAutoConfiguration.class
所以如果导入的Jar包需要依赖这个类就会报错
解决这个问题只需要加入版本号即可

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
   <version>2.2.9.RELEASE</version>
   <type>pom</type>
</dependency>

配置好pom后,我们还需要在Application.java中增加注解@EnableHystrix用于启用Hystrix,否则Hystrix是不生效的。

降级、熔断都是使用注解@HystrixCommand来对某个方法进行标注,其中不同的点在于降级的注解需要一个fallbackMethod而熔断不用。

不过要注意的是,我们定义的fallbackMethod方法参数需要与@HystrixCommand标注的方法参数一致,否则调用就会报错。

在这里插入图片描述
进入正题……

服务降级
当服务B调用服务C时,时间太长阻塞了或者服务C宕机了,我们应该友好的给用户提示一些信息,这也是服务降级的作用。

代码:

    @Autowired
    RestTemplate restTemplate;

    @RequestMapping("/do/{userId}")
    @HystrixCommand(
            fallbackMethod = "fallbackMethod"
    )
    public String doDriver(@PathVariable String userId){
        try{
            Thread.sleep(2900);
        }catch(Exception e){
            e.printStackTrace();
        }
        String url = "http://onlinecar-driver/driver/do/"+userId;
        return restTemplate.getForObject(url,String.class);
    }
    public String  fallbackMethod(String userId){
        return "当前业务繁忙,请稍后重试……";
    }

上面代码的意思是如果调用doDriver超时了或者onlinecar-driver宕机了,就会返回当前业务繁忙,请稍后重试……。使用sleep就是为了模拟服务超时的背景。Hystrix默认的超时时间是1秒。如何配置,最后会给出。
在这里插入图片描述

服务熔断
熔断就会比降级的处理方式更加暴力。如果服务B调用服务C是阻塞了或者服务C宕机了,会直接将服务B于服务C之间的链接断掉,不会返回信息。

看代码:

 @Autowired
    RestTemplate restTemplate;

    @RequestMapping("/do/{userId}")
    @HystrixCommand(
            commandProperties = {           @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="2000")
            }
    )
    public String doDriver(@PathVariable String userId){
        try{
            Thread.sleep(2900);
        }catch(Exception e){
            e.printStackTrace();
        }
        String url = "http://onlinecar-driver/driver/do/"+userId;
        return restTemplate.getForObject(url,String.class);
    }

上面代码的意思是如果调用doDriver超时了或者onlinecar-driver宕机了,就会直接报错。
在这里插入图片描述

配置Hystrix超时时间

一、配置全局默认超时时间
在properties中配置

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3000

二、使用commandKey
在@HystrixCommand中增加commandKey

@HystrixCommand(
    fallbackMethod="fallbackMethod"
    ,commandKey = "driverKey"
)

然后再在properties中配置
hystrix.command.driverKey.execution.isolation.thread.timeoutInMilliseconds=3000

三、使用commandProperties
在@HystrixCommand中增加commandProperties

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

以上就是使用Hystrix的简单实战啦

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值