Hystrix选择信号量策略实现资源隔离
这是我参与更文挑战的第6天,活动详情查看: 更文挑战
接着上一篇信号量文章:【SpringCloud系列】Hystrix选择信号量策略实现资源隔离 (1)
Hystrix 里核心的功能资源隔离,要解决的最核心的问题,将多个依赖服务的调用分别隔离到各自的资源池内。避免对某一个依赖服务的调用,因为依赖服务的接口调用的延迟或者失败,导致服务所有的线程资源全部耗费在这个服务的接口调用。如果某个服务的线程资源全部耗尽,就可能导致服务崩溃,甚至这种故障会不断蔓延,最终可能导致服务雪崩。
信号量适合业务场景:
获取用户数据,都要去获取用户属于哪个地理位置、省、市等,可这些数据存在纯内存中,从本地缓存,可通过cityId,获取cityName,对于直接访问本地内存的逻辑,比较适合信号量做资源隔离。
public class LocalCache {
private static Map<Long,String> city=new HashMap<>();
static{
city.put(1L,"北京");
city.put(2L,"上海");
city.put(3L,"广州");
}
public static String getCityName(Long cityId){
return city.get(cityId);
}
}
选择策略设置为信号量,run()方法中获取本地缓存,同时修改信号量最大并发数为8(默认为10),目的是对获取本地缓存代码进行资源隔离,在接口层通过创建CityCommand,传入cityId,执行execute()方法,获取本地cityName缓存代码将会进行信号量资源隔离
public class CityCommand extends HystrixCommand<String> {
private Long cityId;
public CityCommand(Long cityId){
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("cityGroup")).andCommandPropertiesDefaults(HystrixCommandProperties.Setter().withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE).withExecutionIsolationSemaphoreMaxConcurrentRequests(8)));
this.cityId=cityId;
}
@Override
protected String run() throws Exception {
return LocalCache.getCityName(cityId);
}
}
通过Hystrix 信号量调用本地缓存获取城市名称
@GetMapping("getCityInfo")
@ResponseBody
public String getCityInfo(Long userId){
UserInfoCommand userInfoCommand = new UserInfoCommand(userId);
UserOutpDTO userOutpDTO = userInfoCommand.execute();
Long cityId = userOutpDTO.getCity();
CityCommand cityCommand = new CityCommand(cityId);
String cityName = cityCommand.execute();
return "success";
}
总结
Hystrix选择信号量策略实现资源隔离,一般是对内部一些复杂业务逻辑的访问做限流控制,不需要网络请求的场景使用。