一 介绍缓存
在高并发的场景之下,Hystrix中提供了请求缓存的功能,能够方便地开启和使用请求缓存来优化系统,达到减轻高并发时请求线程的消耗、下降请求响应时间的效果。愿意了解源码的朋友直接求求交流分享技术:二一四七七七五六三三并发
二开启请求缓存功能ide
在实现HystrixCommand或HystrixObservableCommand时,经过重载getCacheKey()方法来开启请求缓存。高并发
例如:优化
public class CommandUsingRequestCache extends HystrixCommand<Boolean> { private final int value; protected CommandUsingRequestCache(int value) { super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")); this.value = value; } @Override protected Boolean run() { return value == 0 || value % 2 == 0; } //经过getCacheKey方法中返回的请求缓存key值,就能让该请求命令具有缓存功能。此时当不一样的外部请求 //处理逻辑调用了同一个依赖服务时,Hystrix会根据getCacheKey方法返回的值区分是不是重复请求, //若是它们的cachekey相同时候,那么该依赖服务值会在第一个请求达到时被真实的调用一次,另一个 //请求则直接从请求缓存中返回结果,因此开启缓存有如下好处: //减小重复请求数,下降依赖服务的并发度 //在同一用户请求的上下文中,相同依赖服务的返回数据始终保持一致。 //请求缓存在run()和construct()执行以前生效,因此能够有效减小没必要要的线程开销。 @Override protected String getCacheKey() { return String.valueOf(value); } }
三 清理失效缓存功能this
使用请求缓存时,若是只是读操做,那么不须要考虑缓存内容是否正确的问题,可是若是请求命令中还有更新数据的操做,那么缓存中的数据就须要咱们在进行写操做时进行及时处理,以防止读操做的请求命令获取到失效的数据。线程
在Hystrix中,能够经过HystrixRequestCache.clear()方法来进行缓存的清理。code
例如:
对象
//当咱们对GetterCommand命令实现了请求缓存以后,那么势必须要为SetterCommand命令实现清理缓存,以保证 //prefixStoredOnRemoteDataStore被更新以后,Hystrix请求缓存中相同的缓存的结果被移除,这样下一次根据id //获取prefixStoredOnRemoteDataStore时,不会从缓存去获取数据 public class CommandUsingRequestCacheInvalidation { /* represents a remote data store */ private static volatile String prefixStoredOnRemoteDataStore = "ValueBeforeSet_"; //根据id获取数据 public static class GetterCommand extends HystrixCommand<String> { private static final HystrixCommandKey GETTER_KEY = HystrixCommandKey.Factory.asKey("GetterCommand"); private final int id; public GetterCommand(int id) { super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("GetSetGet")) .andCommandKey(GETTER_KEY)); this.id = id; } @Override protected String run() { return prefixStoredOnRemoteDataStore + id; } @Override protected String getCacheKey() { return String.valueOf(id); } //该方法从默认的Hystrix并发策略中根据GETTER_KEY获取命令的请求缓存对象HystrixRequestCache的实例 //而后再调用该请求缓存对象的clear方法,对Key为id值的缓存内容进行清理。 public static void flushCache(int id) { HystrixRequestCache.getInstance(GETTER_KEY, HystrixConcurrencyStrategyDefault.getInstance()).clear(String.valueOf(id)); } } //用于更新prefixStoredOnRemoteDataStore的值 public static class SetterCommand extends HystrixCommand<Void> { private final int id; private final String prefix; public SetterCommand(int id, String prefix) { super(HystrixCommandGroupKey.Factory.asKey("GetSetGet")); this.id = id; this.prefix = prefix; } @Override protected Void run() { // persist the value against the datastore prefixStoredOnRemoteDataStore = prefix; //在调用了写prefixStoredOnRemoteDataStore以后,增长了对GetterCommand //中静态方法flushCache的调用,以实现对时效缓存的清理工做。 GetterCommand.flushCache(id); // no return value return null; } } }
总体代码结构以下:blog