Hystrix提供3个专用的请求缓存注解:
@CacheResult——该注解用来标记请求命令返回的结果应该被缓存,必须与@HystrixCommand注解结合使用,属性:cacheKeyMethod
@CacheRemove——该注解使请求命令的缓存失效,失效的缓存根据定义的Key决定,属性:commandKey,cacheKeyMethod
@CacheKey——该注解用来在请求命令的参数上标记,使其作为缓存的Key值,如果没有标注则会使用所有的参数。如果同时还使用了@CacheResult和@CacheRemove注解的cacheKeyMethod方法指定缓存Key的生成,那么该注解将不起作用,属性:value
实例
使用@CacheResult设置请求缓存,在不指定缓存Key的情况下,缓存Key会使用所有的参数(本例中的Long类型id值):
由于要使用Hystrix的请求缓存,必须要先初始化一个HystrixRequestContext实例,也就是说Hystrix请求缓存必须在HystrixRequestContext中才起作用。所以要自定义一个webfilter,将请求放入到HystrixRequestContext中,具体代码如下:
然后,在Spring Application上加上:
服务提供端接口代码如下(每调一次该接口,都生成一个随机数及打印系统时间,来测试客户端调用是否走的缓存):
测试发现,每次客户端每次调用还是没有走缓存(请求id都一样),原因是当在客户端controller里面响应请求时,每一次请求都会有自己独立的线程和ServletContext,而Hystrix请求缓存要求请求必须在同一个HystrixRequestContext中。每一个HystrixReqeustContext都有自己本地线程变量来维护缓存(Map结构),不同的HystrixRequestContext维护的缓存不一样,不能交叉访问。可以在同一个controller里面调两次HelloService来测试缓存是否有效:
从结果中,可以看到缓存起作用了(随机数一样并且服务提供端接口只被调用一次):
移除缓存(@CacheRemove),代码如下:
controller里面测试代码:
从结果上看前两次缓存是有效的,当update后,该id的缓存已经清楚,所以第三次(str3)调用就不走缓存了:
如果使用@CacheKey("id"),会报java.beans.IntrospectionException: Method not found: isId,目前还不知道什么原因。