ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring Cloud Hystrix 学习(二)熔断与降级

2021-09-22 22:03:20  阅读:121  来源: 互联网

标签:降级 String Hystrix Spring 熔断 服务端 test public Cloud


今天来看下Hystrix的熔断与降级。

首先什么是降级?当请求超时、资源不足等情况发生时进行服务降级处理,不调用真实服务逻辑,而是使用快速失败(fallback)方式直接返回一个托底数据,保证服务链条的完整,避免服务雪崩。需要注意的是,服务降级是在客户端层面实现的。接下来通过代码进行一个实践:

 

首先需要添加Hystrix的依赖:

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

application.yml:

server:
  port: 10090

spring:
  application:
    name: spring-cloud-hystrix-test

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:9090/eureka
    fetch-registry: true
    register-with-eureka: true

controller层代码实现:

@RestController
public class TestController {

    @Autowired
    TestService service;

    @GetMapping("/hystrix/test")
    public String helloHystrix() {
        return service.test();
    }
}

service层代码实现:

@Service
public class TestService {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    @HystrixCommand(fallbackMethod = "myFallback")
    public String test() {

        ServiceInstance instance = discoveryClient.getInstances("spring-cloud-service-provider").get(0);
        String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/test";
        return restTemplate.getForObject(url, String.class);
    }

    public String myFallback() {
        return "fallback";
    }
}

这里我们指定了myFallback()作为Fallback方法,我们通过浏览器访问一下这个服务试试看:

调用成功,因为现在我们的服务端并没有出现超时等需要进行降级处理的异常。为了验证降级我们对客户端以及服务端的代码进行微调。

客户端上增加了Hystrix属性中timeout的设置,调整为3秒钟未取到服务端的返回,视为超时:

@HystrixCommand(fallbackMethod = "myFallback", commandProperties = {
        @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
})
public String test() {
ServiceInstance instance = discoveryClient.getInstances("spring-cloud-service-provider").get(0); String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/test"; return restTemplate.getForObject(url, String.class); }

服务端则是增加一个4秒中的sleep:

@RequestMapping(value = "/test", method = RequestMethod.GET)
public String test() throws InterruptedException {
Thread.sleep(4000); return "Hello world!"; }

再次进行验证:

这次可以看到成功触发了降级。

 

再来看一下什么是熔断。当一定时间内,异常请求比例(请求超时、网络故障、服务异常等)达到阈值时,启动熔断器,熔断器一旦启动,则会停止调用具体服务逻辑,通过fallback快速返回托底数据,保证服务链的完整。看上去和降级差不多?不过熔断是在服务端实现,目的是当服务端的某个服务出现异常后为了不影响其他客户端的请求而做出的及时回应。

关于熔断,我们还有必要了解一下熔断机制的三个状态:关闭,开启和半开。最开始是关闭状态,这个时候所有请求都可以通过;如果错误请求达到一定的阈值,就会变成开启状态,此时所有请求短路,直接返回失败的响应;一段时间后,断路器会变成半开状态,如果下一个请求成功了,就关闭断路器,反之就开启断路器。

来看一下具体的代码实现:

@RestController
public class ServiceController {

    @RequestMapping(value = "/test", method = RequestMethod.GET)
    @HystrixCommand(fallbackMethod = "myFallback",
            commandProperties = {
                    @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD, value="1"),
                    @HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS, value="5000")
    })
    public String test() throws Exception {

        System.out.println("test() called...");
        throw new Exception("test exception");
    }

    private String myFallback() {
        return "fallback";
    }
}

这里设置了熔断的一个阈值,也就是10秒内异常请求数达到1次就进行熔断,同时在5秒钟后恢复请求状态。

启动两个浏览器进行验证:

可以看到由于服务端直接抛出异常,两次调用均调用了托底服务,但是服务端却只记录了一次调用,因为第一次调用抛出异常后已经进入熔断状态:

同时由于设置了5秒后恢复请求,我们在5秒后再次尝试调用,服务端又会重新记录正常调用时的信息:

 

参考资料:

https://www.cnblogs.com/yb-ken/p/15068392.html

https://www.cnblogs.com/hellxz/p/8889017.html

https://www.cnblogs.com/bamboocloud/articles/10275090.html

https://www.jianshu.com/p/01efebbfc269

https://blog.csdn.net/wangchengming1/article/details/93191815

https://blog.csdn.net/tongtong_use/article/details/78611225

标签:降级,String,Hystrix,Spring,熔断,服务端,test,public,Cloud
来源: https://www.cnblogs.com/xuzichao/p/15321936.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有