线程池隔离技术,是用 Hystrix 自己的线程去执行调用;而信号量隔离技术,是直接让 tomcat 线程去调用依赖服务。信号量隔离,只是一道关卡,信号量有多少,就允许多少个 tomcat 线程通过它,然后去执行。
适用场景:
- 线程池技术,适合绝大多数场景,比如说我们对依赖服务的网络请求的调用和访问、需要对调用的 timeout 进行控制(捕捉 timeout 超时异常)。
- 信号量技术,适合说你的访问不是对外部依赖的访问,而是对内部的一些比较复杂的业务逻辑的访问,并且系统内部的代码,其实不涉及任何的网络请求,那么只要做信号量的普通限流就可以了,因为不需要去捕获 timeout 类似的问题。
信号量简单 Demo
业务背景里,比较适合信号量的是什么场景呢?
比如说,我们一般来说,缓存服务,可能会将一些量特别少、访问又特别频繁的数据,放在自己的纯内存中。
举个栗子。一般我们在获取到商品数据之后,都要去获取商品是属于哪个地理位置、省、市、卖家等,可能在自己的纯内存中,比如就一个 Map 去获取。对于这种直接访问本地内存的逻辑,比较适合用信号量做一下简单的隔离。
优点在于,不用自己管理线程池啦,不用 care timeout
超时啦,也不需要进行线程的上下文切换啦。信号量做隔离的话,性能相对来说会高一些。
假如这是本地缓存,我们可以通过 cityId,拿到 cityName。
public class LocationCache {
private static Map<Long, String> cityMap = new HashMap<>(); static {
cityMap.put(1L, “北京”);
}
/**
- 通过 cityId 获取 cityName
- @param cityId 城市 id
- @return 城市名
*/
public static String getCityName(Long cityId) {
return cityMap.get(cityId);
}
}
写一个 GetCityNameCommand
,策略设置为信号量。run()
方法中获取本地缓存。我们目的就是对获取本地缓存的代码进行资源隔离。
public class GetCityNameCommand extends HystrixCommand {
private Long cityId; public GetCityNameCommand(Long cityId) {
// 设置信号量隔离策略
super(Setter.withGroupKey(
HystrixCommandGroupKey.Factory.asKey(“GetCityNameGroup”))
.andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
.withExecutionIsolationStrategy(HystrixCommandProperties
.Execut ionIsolationStrategy.SEMAPHORE)));
this.cityId = cityId;
}
@Override
protected String run() {
// 需要进行信号量隔离的代码
return LocationCache.getCityName(cityId);
}
}
在接口层,通过创建 GetCityNameCommand
,传入 cityId,执行 execute()
方法,那么获取本地 cityName 缓存的代码将会进行信号量的资源隔离。
@RequestMapping(“/getProductInfo”)
最后总结
ActiveMQ+Kafka+RabbitMQ学习笔记PDF
关于分布式,限流+缓存+缓存,这三大技术(包含:ZooKeeper+Nginx+MongoDB+memcached+Redis+ActiveMQ+Kafka+RabbitMQ)等等。这些相关的面试也好,还有手写以及学习的笔记PDF,都是啃透分布式技术必不可少的宝藏。以上的每一个专题每一个小分类都有相关的介绍,并且小编也已经将其整理成PDF啦
)等等。这些相关的面试也好,还有手写以及学习的笔记PDF,都是啃透分布式技术必不可少的宝藏。以上的每一个专题每一个小分类都有相关的介绍,并且小编也已经将其整理成PDF啦