基础知识

首次分布式服务系统面临的问题
复杂的分布式体系结构中的应用程序有数十个依赖关系,每个依赖有时候难免发生问题,这个时候可能引发连锁反应,导致整个系统雪崩。
所以就有了Hystrix:

官网地址

Hystrix的主要作用:
服务降级:服务器忙,请稍候再试,不让客户端等待并立刻返回一个友好提示,fallback。发生的场景程序运行异常,超时,服务熔断触发服务降级,线程池/信号池打满也会导致服务降级。
服务熔断:类比保险丝,达到最大服务访问后直接拒绝访问,然后调用服务降级的方法。
服务限流:秒杀高并发操作,严禁一窝蜂的过来拥挤,大家排队,有序进行。

Hystrix使用

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency>
  • 简单的引入案例
    我们首先写一个简单的应用进行压测,从而引出Hystrix
@Service
public class PamentService {public String info(Integer id) {return "线程池" + Thread.currentThread().getName() + "info_ok";}public String info_false(Integer id) {int time = 3;try {TimeUnit.SECONDS.sleep(time);} catch (InterruptedException e) {e.printStackTrace();}return "线程池" + Thread.currentThread().getName() + "timeoutInfo 耗时 : " + time;}
}
@RestController
public class PaymentController {@ResourcePamentService pamentService;@Value("${server.port}")private String port;@GetMapping("/pament/info/{id}")public String getInfo(@PathVariable("id") Integer id) {return pamentService.info(id);}@GetMapping("/pament/info_false/{id}")public String info_false(@PathVariable("id") Integer id) {return pamentService.info_false(id);}
}

接下来我们使用Jmeter进行压测
新建200个线程,每个线程循环100次

发送请求:

原本程序启动访问info的时候基本是0延迟,由于我们发送大量的请求到info_false,占用大量的资源造成拥堵,我们发现访问info的时候出现了卡顿,而接下来我们就要Hystrix来解决这个问题。

同时我们在消费端,去调用这两个服(用openfeign去调用提供端服务,可以参考springcloud服务接口调用OpenFeign这篇文章,这里不再重复),同样开启压测,结果当然一样也会拥堵。下面就来看看Hystrix的具体使用。

服务降级

我们在服务逻辑处配置fallback

@Service
public class PamentService {public String info(Integer id) {return "线程池" + Thread.currentThread().getName() + "info_ok";}@HystrixCommand(fallbackMethod = "timeOutHandler", commandProperties = {// 这个线程池的超时时间是3秒,超过3秒就出错@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")})public String info_false(Integer id) {int time = 5;try {TimeUnit.SECONDS.sleep(time);} catch (InterruptedException e) {e.printStackTrace();}return "线程池" + Thread.currentThread().getName() + "timeoutInfo 耗时 : " + time;}public String timeOutHandler(Integer id) {return "serveice bussy please wait";}

同时在主启动类添加注解:@EnableCircuitBreaker
运行程序,我们休眠5秒才返回结果。但是我们配置了服务3秒之后就超时,所以就会服务降级,结果如下:

注意:timeOutHandler这个方法相当于finally,用来兜底。它所接受的参数应该和服务方法的参数一致,否则会报错。比如这里我们给 info_false配置了服务降级,但是如果我们timeOutHandler不写参数就找不到fallback这个方法。

接下我们再测试一下,发生异常的情况:

public String info_false(Integer id) {int time = 5;int a = 100 / 0; // 人为的制造异常,用于测试异常发生,服务降级try {TimeUnit.SECONDS.sleep(time);} catch (InterruptedException e) {e.printStackTrace();}return "线程池" + Thread.currentThread().getName() + "timeoutInfo 耗时 : " + time;}

毫无疑问它同样会降级

上面演示的是服务端的服务降级。

通常我们客户端可能也有一些限制,比如说3秒还没有返回结果就认为超时。这个时候需要对客户端进行配置。

因为我们是通过feign来调用,所以我们需要开启配置

feign:hystrix:enabled: true #如果处理自身的容错就开启。开启方式与生产端不一样。

@RestController
public class TestController {@ResourceServic servic;@GetMapping("consumer/getinfo/{id}")public String getInfo(@PathVariable("id") Integer id) {return  servic.getInfo(id);}@GetMapping("consumer/getfalse_info/{id}")public String getFalseInfo(@PathVariable("id") Integer id) {return  servic.info_false(id);}@GetMapping("/consumer/payment/hystrix/timeout/{id}")// 如果自己报错,也有兜底的方法@HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500")  //3秒钟以内就是正常的业务逻辑})public String paymentInfo_TimeOut(@PathVariable("id") Integer id){String result = servic.info_false(id);System.out.println("服务熔断了");return result;}//兜底方法public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id){return "我是消费者80,对付支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,(┬_┬)";}
}

主启动类:@EnableHystrix注解
这个是个复合注解:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@EnableCircuitBreaker
public @interface EnableHystrix {}

我们提供服务的地方配置的是5s,这边超时配置的是1.5s很明显是超时,所以会发生服务降级。

按照上面的配置,我们每一个方法都要配置一个fallback,这样好像不太合理,有些fallback的逻辑是相同的。需要把它抽取出来,定义成为全局的fallback。

@RestController
@DefaultProperties(defaultFallback = "paymentTimeOutFallbackMethodGlobal")
public class TestController {@ResourceServic servic;// 添加这个注解,没有指定fallback那么就会直接使用默认的fallback@GetMapping("consumer/getinfo/{id}")@HystrixCommandpublic String getInfo(@PathVariable("id") Integer id) {System.out.println("jfdksdjfjdsjff");int a = 100/ 0;return  servic.getInfo(id);}@GetMapping("consumer/getfalse_info/{id}")public String getFalseInfo(@PathVariable("id") Integer id) {return  servic.info_false(id);}// 这边指定了fallback,那就用自己的fallback@GetMapping("/consumer/payment/hystrix/timeout/{id}")@HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500")  //3秒钟以内就是正常的业务逻辑})public String paymentInfo_TimeOut(@PathVariable("id") Integer id){String result = servic.info_false(id);System.out.println("服务熔断了");return result;}//兜底方法public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id){return "我是消费者80,对付支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,(┬_┬)";}// 全局的兜底方法//兜底方法public String paymentTimeOutFallbackMethodGlobal(){return "我是消费者80,对付支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,(┬_┬)";}
}
```
特别注意:在上面我们配置的时候我提醒了参数一定要一致,但是在配置全局fallback的时候它是无参,因为我们并不知道那个方法发生了异常,所以我们不知道参数类型。我们发现我们上面的业务逻辑和熔断是混合在一起的,那么我们怎么才能解耦呢?
```java
@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT", fallback = ServiceImpl.class)
public interface Service {@GetMapping("/pament/info/{id}")String getInfo(@PathVariable("id") Integer id);@GetMapping("/pament/info_false/{id}")String info_false(@PathVariable("id") Integer id);}
```
```java
@Component
public class ServiceImpl implements Service {@Overridepublic String getInfo(Integer id) {return "服务异常!";}@Overridepublic String info_false(Integer id) {return "服务异常!";}
}
```
这个时候比如我们把服务的提供方直接关掉,这个时候它是异常的,就会走实现类的fallback。
![在这里插入图片描述](https://img-blog.csdnimg.cn/f8035405eb3643fc92eaac9e80cbcbb8.png)
这样的话我们可以我们就实现了fallback与业务的解耦。
但是这里需要特别注意:这种方式是不会处理controller里面的异常的,如下面的代码它不会走服务降级的逻辑,这种方式专注的是某个服务的服务降级。
```java@ResourceService servic;@GetMapping("consumer/getinfo/{id}")public String getInfo(@PathVariable("id") Integer id) {int a = 100 / 0;return  servic.getInfo(id);}
```
#### **服务降熔断**
服务熔断是应对雪崩效应的一种服务链路保护机制。当某个服务出现问题会进行服务降级,等到此服务响应正常后,恢复调佣链路。
我们在服务的实现类上添加方法,配置这个服务熔断的相关配置。
```java// 服务熔断@HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",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"), //失败率达到多少后跳闸})public String paymentCircuitBreaker(@PathVariable("id") Integer id){if (id < 0){throw new RuntimeException("*****id 不能负数");}String serialNumber = IdUtil.simpleUUID();return Thread.currentThread().getName()+"\t"+"调用成功,流水号:"+serialNumber;}// 服务降级fallbackpublic String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id){return "id 不能负数,请稍候再试,(┬_┬)/~~     id: " +id;}
```
controller
```java@GetMapping("/pament/fuse/{id}")public String fuse(@PathVariable("id") Integer id) {return pamentService.paymentCircuitBreaker(id);
}
```
当我们携带负数ID进行请求的时候,就会不断的抛出异常,这个时候失败率超过60%。此时服务就会降级,这个时候我们正常的请求也会走fallback,过一定的时间后再请求会恢复正常。
![在这里插入图片描述](https://img-blog.csdnimg.cn/8b02147c970146798c4d84138f39b3ce.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/35a2cbcaba1341968574a1d041c17296.png)
更多相关的配置(以下图片都来自于尚硅谷):
![在这里插入图片描述](https://img-blog.csdnimg.cn/bb594475a34d45ee920d4e4ab87385ee.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/56b8c33deb4149ce8fe578929a66e538.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/0d527d3808994adb86fe555860a6b690.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/ae753ae528c14a4cb3138f42f97e57a4.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/72d12a398e0845fb8494e395734fc869.png)
### Hystrix图形界面(监控界面)
创建一个新的springboot项目,添加依赖:
```xml
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId></dependency>
```
主启动类添加:@EnableHystrixDashboard
然后访问:http://localhost:9001/hystrix就可以看到如下界面
![在这里插入图片描述](https://img-blog.csdnimg.cn/33b4ef1aeca4403c8408ebbce0bed2f2.png)
在被监控的服务主启动类添加配置:
```java
@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;
}```
在界面填写监控地址:
http://localhost:8001/hystrix.stream
可以看到相关的信息:
![在这里插入图片描述](https://img-blog.csdnimg.cn/edfd194bc51a4ac68edc7474146770c2.png)特别感谢:以上部分图片和代码来源于尚硅谷视频教学。

springcloud(Hystrix服务降级,服务熔断)相关推荐

  1. feign直接走熔断_SpringCloud微服务面试必问:Hystrix 服务降级、熔断

    本文作者:JLSong 本文链接:https://www.cnblogs.com/songjilong/p/12770999.html 1.Hystrix是什么? Hystrix 是一个用于处理分布式 ...

  2. Hystrix断路器原理及实现(服务降级、熔断、限流)

    Hystrix断路器原理及实现(服务降级.熔断.限流) 分布式系统面临的问题 Hystrix重要概念(面试常考) Hystrix案例 Hystrix 服务提供者 Hystrix 服务消费者 原因与解决 ...

  3. 微服务(八)——Hystrix服务降级、熔断、限流(上)

    目录 Hystrix服务降级.熔断.限流 Hystrix是什么 Hystrix停更进维 Hystrix的服务降级熔断限流相关概念 Hystrix支付微服务构建 JMeter高并发压测后卡顿 订单微服务 ...

  4. Spring Cloud H (五)初战服务降级和熔断Hystrix(豪猪哥)

    目录 目录 前言 概述 服务雪崩 服务限流 服务降级 服务熔断 如何理解服务降级和熔断之间的关系 代码实战 Hystrix支付微服务构建 订单微服务调用支付服务出现卡顿 Hystrix之服务降级支付侧 ...

  5. Hystrix 服务降级和熔断

    Hystrix 服务降级和服务熔断 文章目录 Hystrix 服务降级和服务熔断 1.问题的提出 2.Hystrix 3.服务降级 3.1 服务降级实操 3.2 服务降级之客户端 3.3 总结 4.服 ...

  6. SpringCoud - 基础入门(服务注册与发现、服务调用、服务降级与熔断篇)

    SpringCloud:是一系列框架的有序集合,也是一套完整的微服务解决方案.利用SpringBoot的开发便利巧妙的简化了分布式系统基础设施的开发,如发现注册.配置中心.消息总线.负载均衡.断路器. ...

  7. SpringCloud微服务-服务注册发现-负载均衡-服务调用-服务降级-服务网关-配置中心-消息总线-消息驱动-链路追踪-alibaba-nacos-sentinel-seata理论原理分析

    SpringCloud理论技术 概述 ​ Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置中心.消息总 ...

  8. 高并发之服务降级和服务熔断____服务降级、熔断、限流的区别

    高并发之服务降级和服务熔断 服务降级: 服务压力剧增的时候根据当前的业务情况及流量对一些服务和页面有策略的降级,以此环节服务器的压力,以保证核心任务的进行. 同时保证部分甚至大部分任务客户能得到正确的 ...

  9. Hystrix 服务断路器(熔断器 )/服务降级/服务监控 hystrixDashboard

    1. 服务雪崩 多个微服务之间调用的时候, 假设微服务A 调用微服务B和微服务C, 微服务B和微服务C又调用其他的微服务, 这就是所谓的'扇出'. 如果扇出的链路上某个微服务的调用响应时间过长或者不可 ...

  10. 分布式系统架构--服务降级和熔断

    文章目录 参考 一 服务降级 1,降级评判 2,降级等级 3,降级方式 二 服务熔断 1,服务熔断和服务降级的比较 1,服务熔断中需考虑的设计 2,服务熔断恢复需注意的问题 三 Hystrix组件 参 ...

最新文章

  1. BCH链上交易量剧增,超越莱特币
  2. java将本地图片转为bas64_JAVA将图片(本地或者网络资源)转为Base64字符串
  3. UGUI_不规则按钮的响应区域
  4. PyTorch基础(part5)--交叉熵
  5. Software Marketing
  6. L1-011. A-B-PAT团体程序设计天梯赛(GPLT)
  7. openstack nova 源码分析4-nova目录下的driver.py
  8. electron 使用json作为本地存储_使用腾讯云对象存储 COS 作为 Velero 后端存储,实现集群资源备份和还原...
  9. OpenGL基础49:高度贴图(下)
  10. Android 循环缓冲区
  11. windows获取cmd回显以及获取路径
  12. sql 找不到oracle接口,sql-server – sql server链接服务器到oracle返回数据存在时找不到的数据...
  13. 阿里云云计算 40 CDN的概念
  14. Firefox for iOS 终于登陆中国
  15. 总结一些pr的快捷键,让你的剪辑速度翻倍~
  16. 在阿里云上设置CDN
  17. 阿里云对象存储OSS存储照片
  18. 大数据平台docker一键搭建
  19. 来吧 请收藏,测试工程师工作中需要的各种免费工具
  20. Java中byte与short、int、long互转(包含大端,小端)

热门文章

  1. AT指令发送短信流程及接听、拨打电话
  2. android 蓝牙电话号码,Android拨打电话和蓝牙状态监听
  3. 【杂七杂八的笔记】2019CVPR论文快读
  4. R语言—90分钟从入门到精通
  5. 电子招投标系统源码之了解电子招标投标全流程
  6. SLAM 岗位求职与简历书写
  7. 总结JavaScript的数据类型转换
  8. 笔刷分享|每个建模人都在用的笔刷合集
  9. 微信无法连接服务器1-500,GIF表情超过500kb无法添加到微信的解决方法
  10. 一款支持http与dubbo协议互相转换的网关