在微服务架构中,咱们不可避免的与Hystrix打交道,最近在面试过程当中,也老是被问到Hystrix两种熔断方式的区别,今天,就给你们作个小结。java
首先,Hystrix熔断方式主要有两种:面试
线程池隔离数据库
信号量隔离缓存
咱们知道,线程池其实至关于一个容器(池子),容器只有那么大,超过了其限定额度,就溢出啦,线程池有哪些参数,这里就再也不给你们赘述了,有兴趣的朋友能够看看我以前发表的文章,有详细的解释。那么信号量隔离是什么呢?相信有朋友已经想到了,对,就是Semaphore。那么Semaphore是怎么使用的呢?恰好以前写了一段demo,给你们展现下架构
public static void main(String[] args) { Semaphore semaphore = new Semaphore(3); ExecutorService executorService = Executors.newCachedThreadPool(); for (int i = 0; i < 10; i++) { final long num = i; executorService.submit(new Runnable() { @Override public void run() { try { //获取许可 semaphore.acquire(); //执行 System.out.println("Accessing: " + num); Thread.sleep(new Random().nextInt(5000)); // 模拟随机执行时长 //释放 semaphore.release(); System.out.println("Release..." + num); } catch (InterruptedException e) { e.printStackTrace(); } } }); } executorService.shutdown(); }
能够看到,Semaphore其实也是限定大小,同时访问的线程会去争抢获取一个标识,至关于获取token秘钥,拿到的人才有机会执行该逻辑,同时,尤为记住执行完毕以后须要手动释放该标识。
下面,咱们就来讲说线程池和信号量隔离的区别:并发
线程池 | 信号量 | |
线程 | 请求线程和调用provider线程不是同一条线程 | 请求线程和调用provider线程是同一条线程 |
开销 | 排队、调度、上下文切换等 | 无线程切换,开销低 |
异步 | 支持 | 不支持 |
并发支持 | 支持:最大线程池大小 | 支持:最大信号量上限 |
传递Header | 不支持 | 支持 |
支持超时 | 支持 | 不支持 |
那么,他们两又是各自在什么状况下使用呢?dom
线程池隔离异步
请求并发量大,而且耗时长(通常是计算量大或者读数据库):采用线程池隔离,这样的话,能够保证大量的容器线程可用,不会因为服务缘由,一直处于阻塞或者等待状态,快速失败返回。ide
信号量隔离微服务
请求并发量大,而且耗时短(通常是计算量小,或读缓存):采用信号量隔离:由于这类服务的返回每每很是快,不会占用容器线程太长时间,而且减小了线程切换的一些开销,提升了缓存服务的效率