前言
hystrix是netflix开源的一款用于隔离远程服务调用、第三方访问的容错库,又称断路器,为复杂的分布式系统中不可避免的故障提供阻断和动态恢复的能力,避免出现级联故障(俗称雪崩). hystrix目前已经停止官方维护,相关团队已转向开发更具有实时性和自适应能力的组件,例如 resilience4j。即便如此,hystrix能够很好的应对对系统实时状态并非非常敏感的系统场景,内部的实现和设计依然有很多值得自己学习的内容。
概述
hystrix中组织隔离的维度包含了CommandGroup和Command, 为了标识相关业务对象,hystrix使用Key的概念进行区分。例如HystrixCommandGroupKey、HystrixCommandKey、HystrixThreadPoolKey等,这些Key管理hystrix组织业务的主要依据,因此首先理解Key的特性将有利于理解后续的业务逻辑。
Key Factory
HystrixCommandGroupKey: 多个HystrixCommand的分组名标识对象,用于后续基于分组进行告警、报表统计或看板展示等功能;
HystrixCommandKey: 具体HystrixCommand的标识,用于执行熔断、状态统计、监控、请求缓存等功能;
HystrixThreadPoolKey: HystrixThreadPool的标识,如果不指定,默认与HystrixCommandGroupKey保持一致;

模板方式组织Key的操作定义
HystrixKey定义了Key的get的基本操作; HystrixDefaultKey定义了HystrixKey的默认抽象实现; HystrixXXXDefault则通过defaultKey的模板实现具体的业务子类。
以key为索引、以Key信息的Default类为Value, 使用ConcurrentHashMap来存储每种类型的Key对象;
使用map.putIfAbsent方法来避免重复创建Key;
public class InternMap<K, V> {
private final ConcurrentMap<K, V> storage = new ConcurrentHashMap<K, V>();
private final ValueConstructor<K, V> valueConstructor;
public interface ValueConstructor<K, V> {
V create(K key);
}
public InternMap(ValueConstructor<K, V> valueConstructor) {
this.valueConstructor = valueConstructor;
}
public V interned(K key) {
// 先尝试获取
V existingKey = storage.get(key);
V newKey = null;
if (existingKey == null) {
// 未存在时调用构造方法生成,通过putIfAbsent写入新值或返回已存在的值
newKey = valueConstructor.create(key);
existingKey = storage.putIfAbsent(key, newKey);
}
// if absent, put return null;
// else return old value
return existingKey != null ? existingKey : newKey;
}
public int size() {
return storage.size();
}
}
使用内部单例工厂方法封装InternMap的初始化和对HystrixDefaultKey的调用,实现工厂机制。
总结
对于Key的管理使用模板和工厂两种模式的组合,这种组织默认实现和封装内部实现的机制可以借鉴。