HystrixPlugins

  获取并发相关类(HystrixConcurrencyStrategy)、事件通知类(HystrixEventNotifier)、度量信息类(HystrixMetricsPublisher)、Properties配置类(HystrixPropertiesStrategy)、HystrixCommand回调函数类(HystrixCommandExecutionHook)、HystrixDynamicProperties,6类插件。

插件获取:

  HystrixPlugins 首先会去properties(HystrixDynamicProperties)配置下需找相应类型的实现类。

private static <T> T getPluginImplementationViaProperties(Class<T> pluginClass, HystrixDynamicProperties dynamicProperties) {
String classSimpleName = pluginClass.getSimpleName();
// Check Archaius for plugin class.
String propertyName = "hystrix.plugin." + classSimpleName + ".implementation";
String implementingClass = dynamicProperties.getString(propertyName, null).get();
....

  如果返回null,则通过ServiceLoader获取相应类型的实现类。

private <T> T getPluginImplementation(Class<T> pluginClass) {
T p = getPluginImplementationViaProperties(pluginClass, dynamicProperties);
if (p != null) return p;
return findService(pluginClass, classLoader);
}
private static <T> T findService(
Class<T> spi,
ClassLoader classLoader) throws ServiceConfigurationError { ServiceLoader<T> sl = ServiceLoader.load(spi,
classLoader);
for (T s : sl) {
if (s != null)
return s;
}
return null;
}

  如果获取成功,存储变量中。

final AtomicReference<HystrixEventNotifier> notifier = new AtomicReference<HystrixEventNotifier>();
public HystrixEventNotifier getEventNotifier() {
if (notifier.get() == null) {
// check for an implementation from Archaius first
Object impl = getPluginImplementation(HystrixEventNotifier.class);
if (impl == null) {
// nothing set via Archaius so initialize with default
notifier.compareAndSet(null, HystrixEventNotifierDefault.getInstance());
// we don't return from here but call get() again in case of thread-race so the winner will always get returned
} else {
// we received an implementation from Archaius so use it
notifier.compareAndSet(null, (HystrixEventNotifier) impl);
}
}
return notifier.get();
}

  获取HystrixDynamicProperties对象,有点不同,首先使用HystrixDynamicPropertiesSystemProperties配置来需找相应类型的实现类。第二如果查询不同会默认使用Archaius,如果依然没有Archaius支持,会使用HystrixDynamicPropertiesSystemProperties。

private static HystrixDynamicProperties resolveDynamicProperties(ClassLoader classLoader, LoggerSupplier logSupplier) {
HystrixDynamicProperties hp = getPluginImplementationViaProperties(HystrixDynamicProperties.class,
HystrixDynamicPropertiesSystemProperties.getInstance());
if (hp != null) {
logSupplier.getLogger().debug(
"Created HystrixDynamicProperties instance from System property named "
+ "\"hystrix.plugin.HystrixDynamicProperties.implementation\". Using class: {}",
hp.getClass().getCanonicalName());
return hp;
}
hp = findService(HystrixDynamicProperties.class, classLoader);
if (hp != null) {
logSupplier.getLogger()
.debug("Created HystrixDynamicProperties instance by loading from ServiceLoader. Using class: {}",
hp.getClass().getCanonicalName());
return hp;
}
hp = HystrixArchaiusHelper.createArchaiusDynamicProperties();
if (hp != null) {
logSupplier.getLogger().debug("Created HystrixDynamicProperties. Using class : {}",
hp.getClass().getCanonicalName());
return hp;
}
hp = HystrixDynamicPropertiesSystemProperties.getInstance();
logSupplier.getLogger().info("Using System Properties for HystrixDynamicProperties! Using class: {}",
hp.getClass().getCanonicalName());
return hp;
}

HystrixConcurrencyStrategy

  并发相关的策略类。

  获取线程池,实际根据配置创建ThreadPoolExecutor。

/**
获取线程池*/
public ThreadPoolExecutor getThreadPool(final HystrixThreadPoolKey threadPoolKey, HystrixProperty<Integer> corePoolSize, HystrixProperty<Integer> maximumPoolSize, HystrixProperty<Integer> keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
final ThreadFactory threadFactory = getThreadFactory(threadPoolKey);
final int dynamicCoreSize = corePoolSize.get();
final int dynamicMaximumSize = maximumPoolSize.get();
if (dynamicCoreSize > dynamicMaximumSize) {
logger.error("Hystrix ThreadPool configuration at startup for : " + threadPoolKey.name() + " is trying to set coreSize = " +
dynamicCoreSize + " and maximumSize = " + dynamicMaximumSize + ". Maximum size will be set to " +
dynamicCoreSize + ", the coreSize value, since it must be equal to or greater than the coreSize value");
return new ThreadPoolExecutor(dynamicCoreSize, dynamicCoreSize, keepAliveTime.get(), unit, workQueue, threadFactory);
} else {
return new ThreadPoolExecutor(dynamicCoreSize, dynamicMaximumSize, keepAliveTime.get(), unit, workQueue, threadFactory);
}
} public ThreadPoolExecutor getThreadPool(final HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolProperties threadPoolProperties) {
final ThreadFactory threadFactory = getThreadFactory(threadPoolKey);
final boolean allowMaximumSizeToDivergeFromCoreSize = threadPoolProperties.getAllowMaximumSizeToDivergeFromCoreSize().get();
final int dynamicCoreSize = threadPoolProperties.coreSize().get();
final int keepAliveTime = threadPoolProperties.keepAliveTimeMinutes().get();
final int maxQueueSize = threadPoolProperties.maxQueueSize().get();
final BlockingQueue<Runnable> workQueue = getBlockingQueue(maxQueueSize);
if (allowMaximumSizeToDivergeFromCoreSize) {
final int dynamicMaximumSize = threadPoolProperties.maximumSize().get();
if (dynamicCoreSize > dynamicMaximumSize) {
logger.error("Hystrix ThreadPool configuration at startup for : " + threadPoolKey.name() + " is trying to set coreSize = " +
dynamicCoreSize + " and maximumSize = " + dynamicMaximumSize + ". Maximum size will be set to " +
dynamicCoreSize + ", the coreSize value, since it must be equal to or greater than the coreSize value");
return new ThreadPoolExecutor(dynamicCoreSize, dynamicCoreSize, keepAliveTime, TimeUnit.MINUTES, workQueue, threadFactory);
} else {
return new ThreadPoolExecutor(dynamicCoreSize, dynamicMaximumSize, keepAliveTime, TimeUnit.MINUTES, workQueue, threadFactory);
}
} else {
return new ThreadPoolExecutor(dynamicCoreSize, dynamicCoreSize, keepAliveTime, TimeUnit.MINUTES, workQueue, threadFactory);
}
}
private static ThreadFactory getThreadFactory(final HystrixThreadPoolKey threadPoolKey) {
if (!PlatformSpecific.isAppEngineStandardEnvironment()) {
return new ThreadFactory() {
private final AtomicInteger threadNumber = new AtomicInteger(0); @Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r, "hystrix-" + threadPoolKey.name() + "-" + threadNumber.incrementAndGet());
thread.setDaemon(true);
return thread;
} };
} else {
return PlatformSpecific.getAppEngineThreadFactory();
}
}
public BlockingQueue<Runnable> getBlockingQueue(int maxQueueSize) {
if (maxQueueSize <= 0) {
return new SynchronousQueue<Runnable>();
} else {
return new LinkedBlockingQueue<Runnable>(maxQueueSize);
}
}

  在执行callable前提供用户对callable进行分装

public <T> Callable<T> wrapCallable(Callable<T> callable) {
return callable;
}

  获取HystrixRequestVariable

public <T> HystrixRequestVariable<T> getRequestVariable(final HystrixRequestVariableLifecycle<T> rv) {
return new HystrixLifecycleForwardingRequestVariable<T>(rv);
}

HystrixCommandExecutionHook

   hystrix命令执行过程中的回调接口,提供了一下回调接口。

    /**
在命令执行前被调用*/
public <T> void onStart(HystrixInvokable<T> commandInstance) {
//do nothing by default
} /**
当接收到数据时被调用*/
public <T> T onEmit(HystrixInvokable<T> commandInstance, T value) {
return value; //by default, just pass through
} /**
*当命令异常时被调用
* @since 1.2
*/
public <T> Exception onError(HystrixInvokable<T> commandInstance, FailureType failureType, Exception e) {
return e; //by default, just pass through
} /**
*当执行成功后被调用
* @since 1.4
*/
public <T> void onSuccess(HystrixInvokable<T> commandInstance) {
//do nothing by default
} /**
在线程池执行命令前执行*/
public <T> void onThreadStart(HystrixInvokable<T> commandInstance) {
//do nothing by default
} /**
在线程池执行完成后调用*/
public <T> void onThreadComplete(HystrixInvokable<T> commandInstance) {
// do nothing by default
} /**
当开始执行命令时调用*/
public <T> void onExecutionStart(HystrixInvokable<T> commandInstance) {
//do nothing by default
} /**
当执行命令emits a value时调用
*
* @param commandInstance The executing HystrixInvokable instance.
* @param value value emitted
*
* @since 1.4
*/
public <T> T onExecutionEmit(HystrixInvokable<T> commandInstance, T value) {
return value; //by default, just pass through
} /**
执行抛出异常时调用*/
public <T> Exception onExecutionError(HystrixInvokable<T> commandInstance, Exception e) {
return e; //by default, just pass through
} /**
当调用命令成功执行完调用
* @since 1.4
*/
public <T> void onExecutionSuccess(HystrixInvokable<T> commandInstance) {
//do nothing by default
} /**
* Invoked when the fallback method in {@link HystrixInvokable} starts.
*
* @param commandInstance The executing HystrixInvokable instance.
*
* @since 1.2
*/
public <T> void onFallbackStart(HystrixInvokable<T> commandInstance) {
//do nothing by default
} /**
* Invoked when the fallback method in {@link HystrixInvokable} emits a value.
*
* @param commandInstance The executing HystrixInvokable instance.
* @param value value emitted
*
* @since 1.4
*/
public <T> T onFallbackEmit(HystrixInvokable<T> commandInstance, T value) {
return value; //by default, just pass through
} /**
* Invoked when the fallback method in {@link HystrixInvokable} fails with an Exception.
*
* @param commandInstance The executing HystrixInvokable instance.
* @param e exception object
*
* @since 1.2
*/
public <T> Exception onFallbackError(HystrixInvokable<T> commandInstance, Exception e) {
//by default, just pass through
return e;
} /**
* Invoked when the user-defined execution method in {@link HystrixInvokable} completes successfully.
*
* @param commandInstance The executing HystrixInvokable instance.
*
* @since 1.4
*/
public <T> void onFallbackSuccess(HystrixInvokable<T> commandInstance) {
//do nothing by default
} /**
如果从缓存中获取数据时调用*/
public <T> void onCacheHit(HystrixInvokable<T> commandInstance) {
//do nothing by default
} /**
当取消挂载时被调用
* @since 1.5.9
*/
public <T> void onUnsubscribe(HystrixInvokable<T> commandInstance) {
//do nothing by default
}

HystrixEventNotifier

  hystrix命令执行过程中,接收相应的事件通知。

/**
接收到消息后执行
  接受一下消息:
RESPONSE_FROM_CACHE如果该command从缓存中获取数据
CANCELLED 如果command在完成前unsubscrible
EXCEPTION_THROWN 如果command出现异常
EMIT 如果command发送数据
THREAD_POOL_REJECTED 如果线程池抛出reject异常
FAILURE 执行失败异常
  FALLBACK_EMIT执行fallback返回数据
  FALLBACK_SUCCESS执行fallback成功
  FALLBACK_FAILURE执行fallback发生异常
  FALLBACK_REJECTION超过信号量,fallback未被执行。
  FALLBACK_MISSING
  SEMAPHORE_REJECTED信号量模型执行被拒绝。
  SHORT_CIRCUITED熔断
*/
public void markEvent(HystrixEventType eventType, HystrixCommandKey key) {
// do nothing
}
/**
* Called after a command is executed using thread isolation.
* Will not get called if a command is rejected, short-circuited etc.*/
public void markCommandExecution(HystrixCommandKey key, ExecutionIsolationStrategy isolationStrategy, int duration, List<HystrixEventType> eventsDuringExecution) {
// do nothing
}

HystrixMetricsPublisher

  HystrixMetricsPublisherFactory使用该插件来创建HystrixMetricsPublisherCommand、HystrixMetricsPublisherThreadPool、HystrixMetricsPublisherCollapser,并调用相应的initialize方法,这些类用来向第三方publish hystrix的metrics信息。

private final ConcurrentHashMap<String, HystrixMetricsPublisherThreadPool> threadPoolPublishers = new ConcurrentHashMap<String, HystrixMetricsPublisherThreadPool>();

    /* package */ HystrixMetricsPublisherThreadPool getPublisherForThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolMetrics metrics, HystrixThreadPoolProperties properties) {
// attempt to retrieve from cache first
HystrixMetricsPublisherThreadPool publisher = threadPoolPublishers.get(threadPoolKey.name());
if (publisher != null) {
return publisher;
}
// it doesn't exist so we need to create it
publisher = HystrixPlugins.getInstance().getMetricsPublisher().getMetricsPublisherForThreadPool(threadPoolKey, metrics, properties);
// attempt to store it (race other threads)
HystrixMetricsPublisherThreadPool existing = threadPoolPublishers.putIfAbsent(threadPoolKey.name(), publisher);
if (existing == null) {
// we won the thread-race to store the instance we created so initialize it
publisher.initialize();
// done registering, return instance that got cached
return publisher;
} else {
// we lost so return 'existing' and let the one we created be garbage collected
// without calling initialize() on it
return existing;
}
}

  

HystrixPropertiesStrategy

  创建HystrixCommandProperties、HystrixThreadPoolProperties、HystrixCollapserProperties、HystrixTimerThreadPoolProperties

/**
创建HystrixCommandProperties*/
public HystrixCommandProperties getCommandProperties(HystrixCommandKey commandKey, HystrixCommandProperties.Setter builder) {
return new HystrixPropertiesCommandDefault(commandKey, builder);
}/**
创建HystrixThreadPoolProperties*/
public HystrixThreadPoolProperties getThreadPoolProperties(HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolProperties.Setter builder) {
return new HystrixPropertiesThreadPoolDefault(threadPoolKey, builder);
}/**
创建HystrixCollapserProperties*/
public HystrixCollapserProperties getCollapserProperties(HystrixCollapserKey collapserKey, HystrixCollapserProperties.Setter builder) {
return new HystrixPropertiesCollapserDefault(collapserKey, builder);
}
/**
创建HystrixTimerThreadPoolProperties*/
public HystrixTimerThreadPoolProperties getTimerThreadPoolProperties() {
return new HystrixPropertiesTimerThreadPoolDefault();
}

hystrix源码之插件的更多相关文章

  1. hystrix源码之概述

    概述 hystrix核心原理是通过代理执行用户命令,记录命令执行的metrics信息,通过这些metrics信息进行降级和熔断. 源码结构包括一下几个部分: 熔断器 熔断器就是hystrix用来判断调 ...

  2. WeMall微商城源码报名插件Apply的主要源码

    WeMall微信商城源码报名插件Apply,用于商城的签到系统,分享了部分比较重要的代码,供技术员学习参考 AdminController.class.php <?php namespace A ...

  3. WeMall微商城源码投票插件Vote的主要源码

    WeMall微信商城源码投票插件Vote,用于商城的签到系统,分享了部分比较重要的代码,供技术员学习参考 AdminController.class.php <?php namespace Ad ...

  4. Hystrix源码解析

    1. Hystrix源码解析 1.1. @HystrixCommand原理 直接通过Aspect切面来做的 1.2. feign hystrix原理 它的本质原理就是对HystrixCommand的动 ...

  5. MyBatis 源码分析 - 插件机制

    1.简介 一般情况下,开源框架都会提供插件或其他形式的拓展点,供开发者自行拓展.这样的好处是显而易见的,一是增加了框架的灵活性.二是开发者可以结合实际需求,对框架进行拓展,使其能够更好的工作.以 My ...

  6. MyBatis 源码篇-插件模块

    本章主要描述 MyBatis 插件模块的原理,从以下两点出发: MyBatis 是如何加载插件配置的? MyBatis 是如何实现用户使用自定义拦截器对 SQL 语句执行过程中的某一点进行拦截的? 示 ...

  7. 【一起学源码-微服务】Hystrix 源码一:Hystrix基础原理与Demo搭建

    说明 原创不易,如若转载 请标明来源! 欢迎关注本人微信公众号:壹枝花算不算浪漫 更多内容也可查看本人博客:一枝花算不算浪漫 前言 前情回顾 上一个系列文章讲解了Feign的源码,主要是Feign动态 ...

  8. Maven 依赖调解源码解析(二):如何调试 Maven 源码和插件源码

    本文是系列文章<Maven 源码解析:依赖调解是如何实现的?>第二篇,主要介绍如何调试 Maven 源码和插件源码.系列文章总目录参见:https://www.cnblogs.com/xi ...

  9. 分享非常漂亮的WPF界面框架源码及插件化实现原理

      在上文<分享一个非常漂亮的WPF界面框架>中我简单的介绍了一个界面框架,有朋友已经指出了,这个界面框架是基于ModernUI来实现的,在该文我将分享所有的源码,并详细描述如何基于Mod ...

随机推荐

  1. Go 中的内联优化

    文讨论 Go 编译器是如何实现内联的以及这种优化方法如何影响你的 Go 代码. 请注意:本文重点讨论 gc,实际上是 golang.org 的 Go 编译器.讨论到的概念可以广泛用于其他 Go 编译器 ...

  2. Hive中的用户自定义函数

    1.1 关于自定义函数 1)Hive 自带了一些函数,比如:max/min等,但是数量有限,自己可以通过自定义UDF来方便的扩展. 2)当Hive提供的内置函数无法满足你的业务处理需要时,此时就可以考 ...

  3. Inherent Adversarial Robustness of Deep Spiking Neural Networks: Effects of Discrete Input Encoding and Non-Linear Activations

    郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! arXiv:2003.10399v2 [cs.CV] 23 Jul 2020 ECCV 2020 1 https://github.com ...

  4. Java数据结构——图的DFS和BFS

    1.图的DFS: 即Breadth First Search,深度优先搜索是从起始顶点开始,递归访问其所有邻近节点,比如A节点是其第一个邻近节点,而B节点又是A的一个邻近节点,则DFS访问A节点后再访 ...

  5. 查询Linux CPU架构

    一.背景 Ubuntu上需要安装测试个软件wkhtmltopdf,但是下载时,需要知道系统架构,故做记录 二.查看linux架构 dpkg 命令 dpkg 的命令可用于查看 Debian/ Ubunt ...

  6. 解Bug之路-dubbo应用无法重连zookeeper

    前言 dubbo是一个成熟且被广泛运用的框架.饶是如此,在某些极端条件下基于dubbo的应用还会出现无法重连zookeeper的问题.由于此问题容易导致比较大的故障,所以笔者费了一番功夫去定位,现将排 ...

  7. seo兼职顾问多少钱

    http://www.wocaoseo.com/thread-199-1-1.html        随着近几年搜索引挚市场迅猛的发展,网络营销已成为企业销售的一大趋势,越来越多的企业开始投身于网络市 ...

  8. 基于laravel的有偿开源流程引擎

    系统主要文档已经编写完成,具体请前往查看[系统文档](https://www.kancloud.cn/lijianlin/jishullin_workflow_engine/1894424 " ...

  9. pymssql 介绍

    pymssql包是Python语言用于连接SQL Server数据库的驱动程序(或者称作DB API),它是最终和数据库进行交互的工具.SQLAlchemy包就是利用pymssql包实现和SQL Se ...

  10. 【平台开发】— 4.mysql建库建表

    本想着把前端脚手架run起来了,然后就可以借着登录来捋一下前后端交互的过程.但是后端导入JPA的时候就发现了,还没有数据库. 既然是本着学习的目的,那咱也不想只在后端写死返回的数据,要做就做全套. 一 ...