1、限流概念

Hystrix把一个分布式系统的某一个服务打造成一个高可用的服务最重要的手段之一就是资源隔离,即通过限流来限制对某一服务的访问量,比如说对Mysql的访问,为了避免过大的流量直接请求mysql服务,hstrix通过线程池或者信号量技术进行限流访问。

我们了解到Hystrix的两种隔离技术:线程池和信号量。线程池和信号量,也分析了在什么样的场景下使用线程池和信号量,通常来说线程池资源隔离技术一般用于对依赖服务的网络请求访问,需要解决timeout问题。信号量则适合对内部的一些比较复杂的业务逻辑访问,不涉及任何的网络请求,当并发量超过计数器指定值时,直接拒绝。

线程池隔离的最大优点在于:任何一个依赖服务都可以被隔离在自己的线程池内,即使自己的线程池资源填满了,也不会影响任何其他的服务调用。最大缺点在于:增加了cpu的开销,除了tomcat本身的调用线程之外,还有hystrix自己管理的线程池。每个command的执行都依托一个独立的线程,会进行排队,调度,还有上下文切换。

2、资源隔离

(1)线程隔离

Service

  1. //------------------线程隔离
  2. //groupKey 一组command ,如果没有配这个,相同的groupkey会使用同一个线程池
  3. @HystrixCommand(groupKey = "thread1-group",commandKey = "thread1",threadPoolKey = "thread1",commandProperties = {
  4. @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "30000")
  5. },threadPoolProperties = {
  6. @HystrixProperty(name = "coreSize",value = "3"),
  7. @HystrixProperty(name = "maxQueueSize",value = "5")
  8. })
  9. public void thread1(){
  10. try {
  11. Thread.sleep(10000);
  12. } catch (InterruptedException e) {
  13. System.out.println(111);
  14. }
  15. System.out.println(Thread.currentThread().getName());
  16. }

controller

  1. @GetMapping("getThread")
  2. public void getThread(){
  3. System.out.println(Thread.currentThread().getName());
  4. paymentService.thread1();
  5. }

当请求getThread的时候

  1. http-nio-8001-exec-1
  2. hystrix-thread1-1
  3. http-nio-8001-exec-3
  4. hystrix-thread1-2

会发现两个线程池是不一样的。

我现在在service中再添加一个

  1. //------------------线程隔离
  2. //groupKey 一组command ,如果没有配这个,相同的groupkey会使用同一个线程池
  3. @HystrixCommand(groupKey = "thread1-group",commandKey = "thread1",threadPoolKey = "thread1",commandProperties = {
  4. @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")
  5. },threadPoolProperties = {
  6. @HystrixProperty(name = "coreSize",value = "3"),
  7. @HystrixProperty(name = "maxQueueSize",value = "5")
  8. })
  9. public void thread1(){
  10. try {
  11. Thread.sleep(2000);
  12. } catch (InterruptedException e) {
  13. System.out.println(111);
  14. }
  15. System.out.println(Thread.currentThread().getName());
  16. }
  17. @HystrixCommand(groupKey = "thread2-group",commandKey = "thread2",threadPoolKey = "thread2",threadPoolProperties = {
  18. @HystrixProperty(name = "coreSize",value = "3"),
  19. @HystrixProperty(name = "maxQueueSize",value = "5"),
  20. },commandProperties = {
  21. @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1000")})
  22. public void thread2(){
  23. System.out.println(111);
  24. System.out.println(Thread.currentThread().getName());
  25. }

在controller中调用

  1. @GetMapping("getThread")
  2. public void getThread(){
  3. System.out.println(Thread.currentThread().getName());
  4. paymentService.thread1();
  5. paymentService.thread2();
  6. }
  1. http-nio-8001-exec-1
  2. hystrix-thread1-1
  3. 111
  4. hystrix-thread2-1
  1. @HystrixProperty(name = "coreSize",value = "3"), ## 这个表示核心线程数
  2. @HystrixProperty(name = "maxQueueSize",value = "5"), ## 这个表示这个队列中的线程数为5个
  3. 所以这里面有8

(2)信号量隔离