Spring Cloud — 微服务容错保护 Hystrix入门

news/2025/2/22 18:24:41/

微服务之间是通过网络进行相互调用,如果单个服务出现问题,用户调用相关服务时或造成调用延迟或失败,进而可能让整个系统奔溃。提前做好应急措施,当遇到问题时,可及时启动应急方案,让系统进行自我调节和保护。

1 Hystrix

Hystrix 是一个用于处理分布式系统延迟和容错的库,旨在通过隔离服务的访问点、停止级联故障以及提供回退选项来提高系统的整体弹性。

1.1 Hystrix 入门

maven依赖:

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

在Application类增加@EnableCircuitBreaker注解来开启Hystrix支持。

Hystrix 提供降级有2种方式:1)通过@HystrixCommand注解;2)通过继承HystrixCommand或HystrixObservableCommand类。

1.1.1 @HystrixCommand注解

java">@RequestMapping("/home")
@RestController
public class HomeController {private final RestTemplate restTemplate;private final UserService userService;public HomeController(RestTemplate restTemplate, UserService userService) {this.restTemplate = restTemplate;this.userService = userService;}@HystrixCommand(fallbackMethod = "infoCallback")@GetMapping("/info")public String info(String name) {return restTemplate.getForObject("http://provider/user/info?name=" + name + "consumer",String.class);}@HystrixCommand(fallbackMethod = "updateCallback")@PostMapping("/update")public String update(@RequestBody User user) {return userService.update(user);}public String infoCallback(String name) {return "/info 降级";}public String updateCallback(User user) {return "/update 降级," + user;}
}

fallbackMethod所指定的方法要与原方法具有相同的方法签名。

1.1.2 继承HystrixCommand

java">public class UserInfoFailCommand extends HystrixCommand<String> {private final RestTemplate restTemplate;private final String name;public UserInfoFailCommand(RestTemplate restTemplate, String name) {super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")));this.restTemplate = restTemplate;this.name = name;}@Overrideprotected String run() throws Exception {return restTemplate.getForObject("http://provider/user/info?name=" + name,String.class);}@Overrideprotected String getFallback() {return "userInfoFailCommand 降级 info";}
}
java">@RequestMapping("/home")
@RestController
public class HomeController {private final RestTemplate restTemplate;public HomeController(RestTemplate restTemplate) {this.restTemplate = restTemplate;}@GetMapping("/info3")public String info3(String name) {UserInfoFailCommand command = new UserInfoFailCommand(restTemplate,name);return command.execute();}
}

默认是阻塞式的,可提供同步和异步两种方式。同步通过execute()方法直接返回结果,异步执行通过queue()方法返回一个Future对象。

1.1.3 继承HystrixObservableCommand

java">public class UserInfoObservableCommand extends HystrixObservableCommand<String> {private final RestTemplate restTemplate;private final String name;public UserInfoObservableCommand(RestTemplate restTemplate, String name) {super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")));this.restTemplate = restTemplate;this.name = name;}@Overrideprotected Observable<String> construct() {String res = restTemplate.getForObject("http://provider/user/info?name=" + name, String.class);return Observable.just(res + ",UserInfoObservableCommand construct");}@Overrideprotected Observable<String> resumeWithFallback() {return Observable.just("UserInfoObservableCommand info 降级");}
}
java">@RequestMapping("/home")
@RestController
public class HomeController {private final RestTemplate restTemplate;public HomeController(RestTemplate restTemplate) {this.restTemplate = restTemplate;}@GetMapping("/info4")public String info4(String name) {UserInfoObservableCommand command = new UserInfoObservableCommand(restTemplate, name);Iterator<String> iterator = command.observe().toBlocking().getIterator();StringBuilder sb = new StringBuilder();while (iterator.hasNext()) sb.append(iterator.next());return sb.toString();}
}

非阻塞的。只能是异步调用。通过observe()和toObservable()方法返回一个Observable对象。observe()方法会立即发出请求,toObservable()方法只有在订阅该对象时,才会发出请求。

1.1.4 在Feign中使用Hystrix回退

java">@Component
public class UserServiceCallback implements UserService{@Overridepublic String info(String name) {return "info 降级2:" + name;}@Overridepublic String update(User user) {return "update 降级2:" + user;}}
java">@RequestMapping("/home")
@RestController
public class HomeController {private final UserService userService;public HomeController(UserService userService) {this.userService = userService;}@GetMapping("/info2")public String info2(String name) {return userService.info(name + "feign");}@PostMapping("/update")public String update(@RequestBody User user) {return userService.update(user);}
}

需要在配置文件中feign.hystrix.enabled属性设置为true。

1.2 容错机制分析

Hystrix能根据以下条件进行服务降级:

  1. 可配置依赖调用超时时间,当调用超时时,直接返回或进行服务降级。
  2. 为每个依赖关系/服务调用维护一个小的线程池(或信号量),如果已满,那么依赖服务调用将立即被拒绝,而不是排队等待。
  3. 对服务调用的执行状态(成功、失败、超时及线程拒绝等)进行统计,如果某服务调用的错误百分比高于阈值,则可通过手动或自动方式打开断路器。

1.2.1 Hystrix的执行过程

图 Hystrix的执行过程

1 命令封装与执行

通过命令模式,将用户对业务服务请求操作进行封装成HystrixCommand与HystrixObservableCommand。

2 结果缓存是否可用

如果开启了缓存功能,Hystrix在执行命令时首先会检查是否缓存命中,如果是则立即将缓存结果返回,并不再继续执行该命令。

3 断路器是否已打开

如果已打开,说明相应服务不可用,此时进行服务降级。

4 是否有资源执行

判断与该命令相关的线程池和队列是否已满(如果使用信号量隔离,则判断信号量是否已满),如果已满,则不执行该命令,进行服务降级。

5 执行业务逻辑

命令执行过程中,如果超时,那么执行线程将会抛出移除,此时会转入到fallback处理。

6 更新断路器健康数据

在执行业务逻辑的过程中,Hystrix将会把采集到的执行状态(成功、失败、拒绝和超时等)数据提交给断路器。

7 服务降级

在实现服务降级时,最好能提供一个默认的处理结果,该结果最好从内存缓存或一个静态逻辑处理中计算到,不要在有任何网络调用的依赖。

1.2.2 断路器原理分析

断路器根据收集到的命令状态数据,来决定是否打开。如果打开,后续的请求都会进行服务降级处理。然后隔一段时间尝试半开,放一部分流量请求进来,重新统计命令状态数据,如果满足条件,则断路器关闭。


http://www.ppmy.cn/news/1572846.html

相关文章

小蓝相机HDR拍照流程分析

和你一起终身学习&#xff0c;这里是程序员Android 经典好文推荐&#xff0c;通过阅读本文&#xff0c;您将收获以下知识点: HDR 场景下发 3 帧拍照请求HDR 3帧拍照请求帧&#xff08;478,479 480&#xff09;HDR 3帧 result callback帧HDR 算法处理算法编解码处理HDR 拍照log关…

el-table封装一个自定义列配置表格组件(vue3开箱即用)

组件核心功能 拖拽排序&#xff08;使用 vuedraggable&#xff09; 显示/隐藏控制 列宽调整 列固定状态记忆 搜索过滤列 本地存储&#xff08;localStorage&#xff09;可改成接口保存 默认配置恢复 通过 searchText 动态过滤列。 安装拖拽依赖 npm install vuedragg…

vscode环境搭建

目录 一、安装VSCode 二、安装Python 三、安装Anaconda&#xff08;可选&#xff0c;但推荐&#xff09; 四、安装深度学习相关库 五、配置VSCode 六、 结果可视化 一、安装VSCode 访问官网下载&#xff1a;从VSCode官方网站下载适合你操作系统的安装包。安装&#xff1a;运行安…

PrimeFaces实战:IdleMonitor与Ajax的完美结合

在现代的Web开发中&#xff0c;用户交互的实时反馈是一个重要的用户体验环节。PrimeFaces作为一个强大的Java EE UI库&#xff0c;提供了许多便捷的功能组件&#xff0c;其中之一就是IdleMonitor。通过IdleMonitor&#xff0c;我们可以轻松地检测用户何时处于空闲状态以及何时从…

Bug日记:Linux中systemctl restart network失败问题,网络故障

日期 2023年10月25日 问题描述 在尝试使用 systemctl restart network 重启网络服务时&#xff0c;出现以下错误&#xff1a; Job for network.service failed because the control process exited with error code. See "systemctl status network.service" and …

CTFHub技能树-密码口令wp

目录 引言弱口令默认口令 引言 仅开放如下关卡 弱口令 通常认为容易被别人&#xff08;他们有可能对你很了解&#xff09;猜测到或被破解工具破解的口令均为弱口令。 打开环境&#xff0c;是如下界面&#xff0c;尝试一些弱口令密码无果 利用burpsuite抓包&#xff0c;然后爆…

数据结构------单向链表。

一.实现单向链表的头插&#xff0c;头删&#xff0c;尾插&#xff0c;尾删&#xff0c;按位置插&#xff0c;按位置删&#xff0c;按位置修改&#xff0c;按元素查找&#xff0c;按元素修改&#xff0c;按元素删除&#xff0c;单链表的逆置&#xff0c;查找倒数第几个元素&…

word文档提取信息

目录 一、说明二、Aspose-words方式2.1、Aspose-words介绍2.2、Aspose-words使用说明2.3、Aspose-words解析核心代码一、说明 项目中遇到这样的一个需求问题:“一个docx文档,用户根据关键词能搜索定位到文档的哪一页”。docx文档主要有文本、表格、图片、附件这几类组合,为…