当前位置:   article > 正文

Hystrix源码解析_hystrix.threadpool.default.coresize

hystrix.threadpool.default.coresize

Hystrix简介

  在分布式系统中,难免有对外部接口的依赖,而外部接口有可能出现响应缓慢,大量请求超时,大量访问出现异常等情况。出现上面所说的情况有可能是由很多原因导制的,可能是网络抖动,外部系统有没有测出的bug,系统遭遇黑客攻击等。因为一个接口的异常,有可能导制线程阻塞,影响到其它接口的服务,甚至整个系统的服务给拖跨,对外部系统依赖的模块越多,出现的风险也就会越高,Hystrix正是用于解决这样的问题。Hystrix同样是Netflix公司开源的用于解决分布式问题而开源的框架。源码网址为:https://github.com/Netflix/Hystrix。Hystrix提供了如下几种解决方案应对上面说的问题,分别为:

  • 线程池隔离
  • 信号量隔离
  • 熔断
  • 降级回退

Hystrix 版的 Hello World

  • 在pom.xml文件里引入Hystrix依赖的类
  1. <dependencies>
  2. <dependency>
  3. <groupId>com.netflix.hystrix</groupId>
  4. <artifactId>hystrix-core</artifactId>
  5. <version>1.5.13</version>
  6. </dependency>
  7. </dependencies>
  • 编写业务Command
  1. package com.ivan.client.hystrix;
  2. import com.netflix.hystrix.HystrixCommand;
  3. import com.netflix.hystrix.HystrixCommandGroupKey;
  4. public class HelloCommand extends HystrixCommand<String> {
  5. protected HelloCommand() {
  6. super(HystrixCommandGroupKey.Factory.asKey("test"));
  7. }
  8. @Override
  9. protected String run() throws Exception {
  10. //模拟请求外部接口需要的时间长度
  11. Thread.sleep(500);
  12. return "sucess";
  13. }
  14. @Override
  15. protected String getFallback() {
  16. //当外部请求超时后,会执行fallback里的业务逻辑
  17. System.out.println("执行了回退方法");
  18. return "error";
  19. }
  20. }
  • 模拟系统调用
  1. package com.ivan.client.hystrix;
  2. public class App {
  3. public static void main(String[] args) {
  4. HelloCommand command = new HelloCommand();
  5. String result = command.execute();
  6. System.out.println(result);
  7. }
  8. }

当我们增大 HelloCommand run方法里Thread.sleep()方法的时长时,我们可以看到 command.execute()方法调用返回了error。在实际的使用中,当发现第三方接口调用不通的情况下,会调用fallback方法进行降级处理,比如可以返回一段错误提示。

Hystrix线程池隔离

   在分布式的系统里,系统可能对多个外部系统都有依赖关系,比同订单系统同时对会员系统,库存系统统,优惠券系统都有依赖。假如优惠券系统出现访问异常的时候,会超成线程的堆积,对于系统调用库存系统与会员系统的业务也不可用。而通过线程池能够将不同的业务由不同的线程池处理,从而做到保护其它业务能够正常访问。下面就来看看Hystrix是根据什么来创建线程的。

  • 找到HystrixCommand的父类AbstractCommand, 里面有个构造方法,从构造方法可以看出里这里定义了 threadPool对象。代码如下,关键代码都有做相应的注释
  1. /**
  2. 这个方法是AbstractCommand的构造方法,里面用于初使化AbstractCommand,包括circuitBreaker 与线程池对象都在这里进行构造
  3. **/
  4. protected AbstractCommand(HystrixCommandGroupKey group, HystrixCommandKey key, HystrixThreadPoolKey threadPoolKey, HystrixCircuitBreaker circuitBreaker, HystrixThreadPool threadPool,
  5. HystrixCommandProperties.Setter commandPropertiesDefaults, HystrixThreadPoolProperties.Setter threadPoolPropertiesDefaults,
  6. HystrixCommandMetrics metrics, TryableSemaphore fallbackSemaphore, TryableSemaphore executionSemaphore,
  7. HystrixPropertiesStrategy propertiesStrategy, HystrixCommandExecutionHook executionHook) {
  8. //commandGroup对象,用于组织一类业务相关的对象
  9. this.commandGroup = initGroupKey(group);
  10. // commandKey默认是以类为为名称的
  11. this.commandKey = initCommandKey(key, getClass());
  12. this.properties = initCommandProperties(this.commandKey, propertiesStrategy, commandPropertiesDefaults);
  13. //这个方法里定义了TheradPool里的关键字,默认以传入的commandGroup 的name做为key的名称
  14. this.threadPoolKey = initThreadPoolKey(threadPoolKey, this.commandGroup, this.properties.executionIsolationThreadPoolKeyOverride().get());
  15. this.metrics = initMetrics(metrics, this.commandGroup, this.threadPoolKey, this.commandKey, this.properties);
  16. this.circuitBreaker = initCircuitBreaker(this.properties.circuitBreakerEnabled().get(), circuitBreaker, this.commandGroup, this.commandKey, this.properties, this.metrics);
  17. //这里就是线程池对象啦。
  18. this.threadPool = initThreadPool(threadPool, this.threadPoolKey, threadPoolPropertiesDefaults);
  19. //Strategies from plugins
  20. this.eventNotifier = HystrixPlugins.getInstance().getEventNotifier();
  21. this.concurrencyStrategy = HystrixPlugins.getInstance().getConcurrencyStrategy();
  22. HystrixMetricsPublisherFactory.createOrRetrievePublisherForCommand(this.commandKey, this.commandGroup, this.metrics, this.circuitBreaker, this.properties);
  23. this.executionHook = initExecutionHook(executionHook);
  24. this.requestCache = HystrixRequestCache.getInstance(this.commandKey, this.concurrencyStrategy);
  25. this.currentRequestLog = initRequestLog(this.properties.requestLogEnabled().get(), this.concurrencyStrategy);
  26. /* fallback semaphore override if applicable */
  27. this.fallbackSemaphoreOverride = fallbackSemaphore;
  28. /* execution semaphore override if applicable */
  29. this.executionSemaphoreOverride = executionSemaphore;
  30. }
  31. /**
  32. 这个方法用于得到HystrixThreadPoolKey 对象, Hystrix内部有大量的Key对象,可以简单理解这些 Key都是相应对象的唯一标识。从代码里可以看出,默认情况下Hystrix采用的是commandGroup 的name做为Thread Pool的key值。
  33. **/
  34. private static HystrixThreadPoolKey initThreadPoolKey(HystrixThreadPoolKey threadPoolKey, HystrixCommandGroupKey groupKey, String threadPoolKeyOverride) {
  35. if (threadPoolKeyOverride == null) {
  36. // we don't have a property overriding the value so use either HystrixThreadPoolKey or HystrixCommandGroup
  37. if (threadPoolKey == null) {
  38. /* use HystrixCommandGroup if HystrixThreadPoolKey is null */
  39. return HystrixThreadPoolKey.Factory.asKey(groupKey.name());
  40. } else {
  41. return threadPoolKey;
  42. }
  43. } else {
  44. // we have a property defining the thread-pool so use it instead
  45. return HystrixThreadPoolKey.Factory.asKey(threadPoolKeyOverride);
  46. }
  47. }
  48. /**
  49. 在这里将调用具体的构造线程池的方法。
  50. **/
  51. private static HystrixThreadPool initThreadPool(HystrixThreadPool fromConstructor, HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolProperties.Setter threadPoolPropertiesDefaults) {
  52. if (fromConstructor == null) {
  53. // get the default implementation of HystrixThreadPool
  54. return HystrixThreadPool.Factory.getInstance(threadPoolKey, threadPoolProperties
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/978748
推荐阅读
相关标签
  

闽ICP备14008679号