1. Hystrix简介
在桦甸等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供成都网站设计、网站建设 网站设计制作按需网站设计,公司网站建设,企业网站建设,成都品牌网站建设,营销型网站建设,外贸网站制作,桦甸网站建设费用合理。
Hystrix是Netflix开源的一款针对分布式系统的延迟和容错库,目的是用来隔离分布式服务故障。它提供线程和信号量隔离,以减少不同服务之间资源竞争带来的相互影响;提供优雅降级机制;提供熔断机制使得服务可以快速失败,而不是一直阻塞等待服务响应,并能从中快速恢复。Hystrix通过这些机制来阻止级联失败并保证系统弹性、可用。下图是一个典型的分布式服务实现。
首先,当大多数人在使用Tomcat时,多个HTTP服务会共享一个线程池,假设其中一个HTTP服务访问的数据库响应非常慢,这将造成服务响应时间延迟增加,大多数线程阻塞等待数据响应返回,导致整个Tomcat线程池都被该服务占用,甚至拖垮整个Tomcat。因此,如果我们能把不同HTTP服务隔离到不同的线程池,则某个HTTP服务的线程池满了也不会对其他服务造成灾难性故障。这就需要线程隔离或者信号量隔离来实现了。
使用线程隔离或信号隔离的目的是为不同的服务分配一定的资源,当自己的资源用完,直接返回失败而不是占用别人的资源。
同理,如“HTTP服务1”和“HTTP服务2”要分别访问远程的“分布式服务A”和“分布式服务B”,假设它们共享线程池,那么其中一个服务在出现问题时也会影响到另一个服务,因此,我们需要进行访问隔离,可以通过Hystrix的线程池隔离或信号量隔离来实现。
其次,“分布式服务B”依赖了“分布式服务D”和“分布式服务E”,其中“分布式服务D”是一个可降级的服务,意思是出现故障时(如超时、网络故障)可以暂时屏蔽掉或者返回缓存脏数据,如访问商品详情页时,可以暂时屏蔽掉上边的商家信息,不会影响用户下单流程。
当我们依赖的服务访问超时时,要提供降级策略。比如,返回托底数据阻止级联故障。当因为一些故障(如网络故障)使得服务可用率下降时,要能及时熔断,一是快速失败,二是可以保护远程分布式服务。
到此我们大体了解了Hystrix是用来解决什么问题的。
接下来,我们来看下如何使用Hystrix,本书使用的版本是Hystrix- 1.5.6。
2. 隔离示例
以线程池隔离为示例,会为不同的服务设置不同的线程池,从而实现相互隔离。
为不同的HTTP服务设置不同的线程池,为不同的分布式服务调用设置不同的线程池。
假设我们现在要调用一个获取库存服务,通过封装一个命令GetStockServiceCommand来实现。
- public class GetStockServiceCommand extends HystrixCommand
{ - private StockService stockService;
- public GetStockServiceCommand() {
- super(setter());
- }
- private static Setter setter() {
- //服务分组
- HystrixCommandGroupKey groupKey = HystrixCommandGroupKey.Factory. asKey("stock");
- //服务标识
- HystrixCommandKey commandKey =HystrixCommandKey.Factory. asKey("getStock");
- //线程池名称
- HystrixThreadPoolKey threadPoolKey = HystrixThreadPoolKey.Factory. asKey("stock-pool");
- //线程池配置
- HystrixThreadPoolProperties.Setter threadPoolProperties =HystrixThreadPoolProperties.Setter threadPoolProperties =HystrixThreadPoolProperties.Setter()
- .withCoreSize(10)
- .withKeepAliveTimeMinutes(5)
- .withMaxQueueSize(Integer.MAX_VALUE)
- .withQueueSizeRejectionThreshold(10000);
- //命令属性配置
- HystrixCommandProperties.Setter commandProperties = HystrixCommandProperties.Setter()
- .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD);
- return HystrixCommand.Setter
- .withGroupKey(groupKey)
- .andCommandKey(commandKey)
- .andThreadPoolKey(threadPoolKey)
- .andThreadPoolPropertiesDefaults(threadPoolProperties)
- .andCommandPropertiesDefaults(commandProperties);
- }
- @Override
- protectedString run() throws Exception {
- return stockService.getStock();
- }
- }
几个重要组件如下。
此处可以粗粒度实现隔离,也可以细粒度实现隔离,如下所示。
如上配置是在应用启动时就配置好了,在实际运行过程中,我们可能随时调整其中一些参数,如线程池大小、队列大小,此时,可以使用如下方式进行动态配置。
- String dynamicQueueSizeRejectionThreshold = "hystrix.threadpool."+ "stock-pool" + ".queueSizeRejectionThreshold";
- Configuration configuration = ConfigurationManager.getConfigInstance();
- configuration.setProperty(dynamicQueueSizeRejectionThreshold,100);
如果是改变线程池配置,则是"hystrix.threadpool."+ threadPoolKey + propertyName;如果是改变命令属性配置,则是"hystrix.command." + commandKey + propertyName。
接下来就可以通过如下方式创建命令。
- GetStockServiceCommand command = new GetStockServiceCommand(newStockService());
然后通过如下方式同步调用。
- String result = command.execute();
或者返回Future从而实现异步调用。
- Future
future = command.queue();
或者配合RxJava实现响应式编程。
- Observable
observe =command.observe(); - observe.asObservable().subscribe((result) -> {
- System.out.println(result);
- });
在应用Hystrix时,首先需要把服务封装成HystrixCommand,即命令模式实现,然后就可以通过同步/异步/响应式模式来调用服务。
信号量隔离通过如下配置即可。
- HystrixCommandProperties.Setter commandProperties= HystrixCommandProperties.Setter() .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE)
- .withExecutionIsolationSemaphoreMaxConcurrentRequests(50);
信号量隔离只是限制了总的并发数,服务使用主线程进行同步调用,即没有线程池。因此,如果只是想限制某个服务的总并发调用量或者调用的服务不涉及远程调用的话,可以使用轻量级的信号量来实现。
GetStockServiceCommand不是单例,不能重用,必须每次使用创建一个。如果觉得Hystrix太麻烦或者太重,则可以参考Hystrix思路设计自己的组件。
【本文是专栏作者张开涛的原创文章,作者微信公众号:开涛的博客( kaitao-1234567)】
戳这里,看该作者更多好文
当前名称:隔离术之使用Hystrix实现隔离
标题链接:http://www.csdahua.cn/qtweb/news47/68447.html
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网