【SpringBoot】SpringBoot 之 Hystrix服务隔离(十二)
2021-02-15 07:18
标签:var 失败 mic 判断 接受 mapping cal 依赖 interrupt 当大多数人在使用Tomcat时,多个HTTP服务会共享一个线程池,假设其中一个HTTP服务访问的数据库响应非常慢,这将造成服务响应时间延迟增加,大多数线程阻塞等待数据响应返回,导致整个Tomcat线程池都被该服务占用,甚至拖垮整个Tomcat。因此,如果我们能把不同HTTP服务隔离到不同的线程池,则某个HTTP服务的线程池满了也不会对其他服务造成灾难性故障。这就需要线程隔离或者信号量隔离来实现了。 使用线程隔离或信号隔离的目的是为不同的服务分配一定的资源,当自己的资源用完,直接返回失败而不是占用别人的资源。 Hystrix实现服务隔离两种方案 Hystrix的资源隔离策略有两种,分别为:线程池和信号量。 优点: 1、 使用线程池隔离可以完全隔离第三方应用,请求线程可以快速放回。 2、 请求线程可以继续接受新的请求,如果出现问题线程池隔离是独立的不会影响其他应用。 3、 当失败的应用再次变得可用时,线程池将清理并可立即恢复,而不需要一个长时间的恢复。 4、 独立的线程池提高了并发性 缺点: 线程池隔离的主要缺点是它们增加计算开销(CPU)。每个命令的执行涉及到排队、调度和上 下文切换都是在一个单独的线程上运行的。 1、使用上一章项目工程,在服务端项目的业务类Service中编写如下方法: 2、在controller中调用该方法 3、重启项目,使用JMeter进行并发测试,测试url地址:http://localhost:8008/payment/hystrix/thread/1 测试发现,有一部分请求调用了fallback方法,一部分正常响应 使用一个原子计数器(或信号量)来记录当前有多少个线程在运行,当请求进来时先判断计数 器的数值,若超过设置的最大线程个数则拒绝该请求,若不超过则通行,这时候计数器+1,请求返 回成功后计数器-1。 与线程池隔离最大不同在于执行依赖代码的线程依然是请求线程 提示:信号量的大小可以动态调整, 线程池大小不可以 1、使用上一章项目工程,在服务端项目的业务类Service中编写如下方法: 2、在controller中调用该方法 3、重启项目,使用JMeter进行并发测试,测试url地址:http://localhost:8008/payment/hystrix/semaphore/1 测试发现,有一部分请求调用了fallback方法,一部分正常响应 【SpringBoot】SpringBoot 之 Hystrix服务隔离(十二) 标签:var 失败 mic 判断 接受 mapping cal 依赖 interrupt 原文地址:https://www.cnblogs.com/h--d/p/12716811.html服务隔离介绍
线程池方式
线程池方式案例
1 // 服务限流
2 @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_Thread",
3 // 属性设置参考:HystrixCommandProperties
4 commandProperties = {
5 // 隔离策略,有THREAD和SEMAPHORE
6 @HystrixProperty(name="execution.isolation.strategy", value="THREAD")
7 },
8 threadPoolProperties = {
9 // 线程池核心线程数
10 @HystrixProperty(name = "coreSize", value = "3"),
11 // 队列最大长度
12 @HystrixProperty(name = "maxQueueSize", value = "5"),
13 // 排队线程数量阈值,默认为5,达到时拒绝,如果配置了该选项,队列的大小是该队列
14 @HystrixProperty(name = "queueSizeRejectionThreshold", value = "7")
15 })
16 public String paymentCircuitBreakerThread(@PathVariable("id") Integer id){
17 int second = 500;
18 try {
19 // 休眠500毫秒
20 TimeUnit.MILLISECONDS.sleep(second);
21 } catch (InterruptedException e) {
22 // e.printStackTrace();
23 }
24 // 异常
25 // int n = 10/0;
26 String result = "线程池:" + Thread.currentThread().getName()
27 + ",paymentCircuitBreakerThreadPool,ID == " + id
28 + ",耗时" + second + "毫秒";
29 return result;
30 }
31
32 public String paymentCircuitBreaker_Thread(@PathVariable("id") Integer id){
33 return " paymentCircuitBreaker_Thread 服务限流,ID == " + id;
34 }
1 // 线程
2 @GetMapping(value = "/payment/hystrix/thread/{id}")
3 public String paymentCircuitBreakerThreadPool(@PathVariable("id") Integer id) {
4 String result = paymentService.paymentCircuitBreakerThread(id);
5 log.info("result===" + result);
6 return result;
7 }
信号量方式
信号量方式案例
1 // 服务限流
2 @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_Semaphore",
3 // 属性设置参考:HystrixCommandProperties
4 commandProperties = {
5 // 隔离策略,有THREAD和SEMAPHORE
6 // THREAD - 它在单独的线程上执行,并发请求受线程池中的线程数量的限制(默认)
7 // SEMAPHORE - 它在调用线程上执行,并发请求受到信号量计数的限制
8 @HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE"),
9 // 设置在使用时允许到HystrixCommand.run()方法的最大请求数。默认值:10 ,SEMAPHORE模式有效
10 @HystrixProperty(name="execution.isolation.semaphore.maxConcurrentRequests", value="1")
11
12 })
13 public String paymentCircuitBreakerSemaphore(@PathVariable("id") Integer id){
14 int second = 500;
15 try {
16 // 休眠500毫秒
17 TimeUnit.MILLISECONDS.sleep(second);
18 } catch (InterruptedException e) {
19 // e.printStackTrace();
20 }
21 // 异常
22 // int n = 10/0;
23 String result = "线程池:" + Thread.currentThread().getName()
24 + ",paymentCircuitBreaker_Semaphore,ID == " + id
25 + ",耗时" + second + "毫秒";
26 return result;
27 }
28
29 public String paymentCircuitBreaker_Semaphore(@PathVariable("id") Integer id){
30 return " paymentCircuitBreaker_Semaphore 服务限流,ID == " + id;
31 }
1 // 信号量
2 @GetMapping(value = "/payment/hystrix/semaphore/{id}")
3 public String paymentCircuitBreakerLimit(@PathVariable("id") Integer id) {
4 String result = paymentService.paymentCircuitBreakerSemaphore(id);
5 log.info("result===" + result);
6 return result;
7 }
文章标题:【SpringBoot】SpringBoot 之 Hystrix服务隔离(十二)
文章链接:http://soscw.com/index.php/essay/55550.html