开启请求缓存

  请求缓存在run()和construce()执行之前生效,所以可以有效减少不必要的线程开销。你可以通过实现getCachekey()方法来开启请求缓存。

package org.hope.hystrix.example.request.cache;

import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey; public class CommandUsingRequestCache extends HystrixCommand<Boolean> {
private final int value; public CommandUsingRequestCache(int value) {
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
this.value = value;
} @Override
protected Boolean run() throws Exception {
return value == 0 || value % 2 == 0;
} @Override
protected String getCacheKey() {
return String.valueOf(value);
}
}

单元测试

package org.hope.hystrix.example.request.cache;

import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
import org.hope.hystrix.example.request.cache.CommandUsingRequestCache;
import org.junit.Test; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; public class CommandUsingRequestCacheTest { @Test
public void testWithoutCacheHits() {
HystrixRequestContext cxt = HystrixRequestContext.initializeContext();
try {
assertTrue(new CommandUsingRequestCache(2).execute());
assertTrue(new CommandUsingRequestCache(1).execute());
} finally {
cxt.shutdown();
}
} @Test
public void testWithCacheHits() {
HystrixRequestContext cxt = HystrixRequestContext.initializeContext();
try {
CommandUsingRequestCache command2a = new CommandUsingRequestCache(2);
CommandUsingRequestCache command2b = new CommandUsingRequestCache(2); assertTrue(command2a.execute());
// this is the first time we've executed this command with the value of "2" so it should not be from cache
// assertFalse(command2a.isResponseFromCache());
System.out.println(command2a.isResponseFromCache()); assertTrue(command2b.execute());
// this is the second time we've executed this command with the same value so it should return from cache
// assertTrue(command2b.isResponseFromCache());
System.out.println(command2b.isResponseFromCache());
} finally {
cxt.shutdown();
} // start a new request context
cxt = HystrixRequestContext.initializeContext();
try {
CommandUsingRequestCache command3b = new CommandUsingRequestCache(2);
assertTrue(command3b.execute());
// this is a new request context so this should not come from cache
// assertFalse(command3b.isResponseFromCache());
System.out.println(command3b.isResponseFromCache());
} finally {
cxt.shutdown();
}
}
}

清理失效缓存

package org.hope.hystrix.example.request.cache;

import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixRequestCache;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategyDefault; /**
* 清理缓存
*/
public class CommandUsingRequestCacheInvalidation{ private static volatile String prefixStoredOnRemoteDataStore = "ValueBeforeSet_"; 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() throws Exception {
return prefixStoredOnRemoteDataStore + id;
} @Override
protected String getCacheKey() {
return String.valueOf(id);
} //Allow the cache to be flushed for this object.
public static void flushCache(int id) {
HystrixRequestCache.getInstance(GETTER_KEY, HystrixConcurrencyStrategyDefault.getInstance()).clear(String.valueOf(id));
} } 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() throws Exception {
// persist the value against the datastore
prefixStoredOnRemoteDataStore = prefix;
// flush the cache
GetterCommand.flushCache(id);
return null;
}
} }

单元测试:

package org.hope.hystrix.example.request.cache;

import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
import org.junit.Test; /**
* Created by lisen on 2017/12/27.
*/
public class CommandUsingRequestCacheInvalidationTest { @Test
public void flushCacheTest() {
HystrixRequestContext context = HystrixRequestContext.initializeContext();
System.out.println(new CommandUsingRequestCacheInvalidation.GetterCommand(1).execute()); CommandUsingRequestCacheInvalidation.GetterCommand commandAgainstCache = new CommandUsingRequestCacheInvalidation.GetterCommand(1); System.out.println(commandAgainstCache.isResponseFromCache()); //false
System.out.println(commandAgainstCache.execute());
System.out.println(commandAgainstCache.isResponseFromCache()); //false
// set the new value
new CommandUsingRequestCacheInvalidation.SetterCommand(1, "ValueAfterSet_").execute();
// fetch it again
CommandUsingRequestCacheInvalidation.GetterCommand commandAfterSet = new CommandUsingRequestCacheInvalidation.GetterCommand(1);
//the getter should return with the new prefix, not the value from cache
System.out.println(commandAfterSet.isResponseFromCache());
System.out.println(commandAfterSet.execute());
}
}

注解的实现请求缓存

注解 描述 属性
@CacheResult 改注解用来标记请求命令返回的结果应该被缓存,它必须与@HystrixCommand注解结合使用 cacheKeyMethod
@CacheRemove 该注解用来让请求命令的缓存失效,失效的缓存根据定义的key决定 commandKey,cacheKeyMethod
@CacheKey

改注解用来在请求命令的参数上标记,使其作为缓存的Key值,如果没有标注则会使用所有参数。如果同时还使用了@CacheResult和

@CacheRemove注解的cacheKeyMethod方法指定缓存Key的生成,那么该注解将不会起作用

value

设置缓存

package org.hope.hystrix.example.request.cache;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheKey;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheResult;
import org.hope.hystrix.example.model.User;
import org.springframework.stereotype.Service;
@Service
public class RequestCacheAnnotation { /**
* 返回的结果会置入请求缓存中,缓存的key值会使用所有的方法入参,
* 也就是这里Long类型的id
*/
@CacheResult
@HystrixCommand
public String getUserById(Long id) {
return "你好" + id;
} /**
* cacheKeyMethod可以为缓存指定具体的缓存key
*/
@CacheResult(cacheKeyMethod = "getUserByIdCacheKey")
@HystrixCommand
public String getUserById2(Long id) {
return "你好:" + id;
} public String getUserByIdCacheKey(Long id) {
return String.valueOf(id);
} /**
* 通过@CacheKey来定义具体的缓存Key。
* 但是注意,@CacheKey的优先级比@CacheResult(cacheKeyMethod = "")的优先级低。
* 如果已经使用了cacheKeyMethod指定缓存Key的生成函数,那么@CacheKey注解不会生效
*/
@CacheResult
@HystrixCommand
public String getUserById3(@CacheKey("id") Long id) {
return "你好:" + id;
} /**
* @CacheKey还可以通过访问参数对象内部属性作为缓存key
* 这里指定了User对象id属性作为缓存key
*/
@CacheResult
@HystrixCommand
public String getUserById4(@CacheKey("id") User user) {
return "你好" + user.getId();
} }

清理缓存

package org.hope.hystrix.example.request.cache;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheKey;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheRemove;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheResult;
import org.hope.hystrix.example.model.User; public class RequestClearCacheAnnotation { @CacheResult
@HystrixCommand
public User getUserById(@CacheKey("id") Long id) {
User u = new User();
u.setId(id);
return u;
} /**
* 用@CacheRemove来清理失效缓存,其中commandKey是必须指定的
*/
@CacheRemove(commandKey = "getUserById")
@HystrixCommand
public void update(@CacheKey("id") User user) {
User u = new User();
u.setId(20L);
} public String getUserById(User user) {
return String.valueOf(user.getId());
}
}

https://gitee.com/huayicompany/Hystrix-learn/tree/master/hystrix-example

参考:

[1]Github,https://github.com/Netflix/Hystrix/wiki/How-it-Works

[2] 《SpringCloud微服务实战》,电子工业出版社,翟永超

Hystrix-request cache(请求缓存)的更多相关文章

  1. hystrix中request cache请求缓存

    有一个概念,叫做reqeust context,请求上下文,一般来说,在一个web应用中, 我们会在一个filter里面,对每一个请求都施加一个请求上下文,就是说,tomcat容器内,每一次请求,就是 ...

  2. SpringCloud实战-Hystrix线程隔离&请求缓存&请求合并

    接着上一篇的Hystrix进行进一步了解. 当系统用户不断增长时,每个微服务需要承受的并发压力也越来越大,在分布式环境中,通常压力来自对依赖服务的调用,因为亲戚依赖服务的资源需要通过通信来实现,这样的 ...

  3. SpringCloud实战4-Hystrix线程隔离&请求缓存&请求合并

    接着上一篇的Hystrix进行进一步了解. 当系统用户不断增长时,每个微服务需要承受的并发压力也越来越大,在分布式环境中,通常压力来自对依赖服务的调用,因为亲戚依赖服务的资源需要通过通信来实现,这样的 ...

  4. Spring-cloud (八) Hystrix 请求缓存的使用

    前言: 最近忙着微服务项目的开发,脱更了半个月多,今天项目的初版已经完成,所以打算继续我们的微服务学习,由于Hystrix这一块东西好多,只好多拆分几篇文章写,对于一般对性能要求不是很高的项目中,可以 ...

  5. hystrix源码之请求缓存

    HystrixRequestCache 请求缓存.内部是一个静态ConcurrentHashMap存储各个命令的缓存器,RequestCacheKey为key,HystrixRequestCache为 ...

  6. Hystrix框架5--请求缓存和collapser

    简介 在Hystrix中有个Request的概念,有一些操作需要在request中进行 缓存 在Hystrix调用服务时,如果只是查询接口,可以使用缓存进行优化,从而跳过真实访问请求. 应用 需要启用 ...

  7. Spring Cloud(Dalston.SR5)--Hystrix 断路器-合并请求

    在 Spring Cloud 中可以使用注解的方式来支持 Hystrix 的合并请求,缓存与合并请求功能需要先初始化请求上下文才能实现,因此,必须实现 javax.servlet.Filter 用于创 ...

  8. http cache & 浏览器缓存,存储位置的优先级,条件?

    http cache & 浏览器缓存,存储位置的优先级,条件? memory cache disk cache 浏览器缓存,存储位置的优先级,条件, 机制,原理是什么? from memory ...

  9. 利用LRU策略实现Axios请求缓存

    业务场景 前一段时间刚做完一个项目,先说一下业务场景,有别于其他的前端项目,这次的项目是直接调用第三方服务的接口,而我们的服务端只做鉴权和透传,第三方为了灵活,把接口拆的很零散,所以这个项目就像扔给你 ...

随机推荐

  1. python 常用算法

    算法就是为了解决某一个问题而采取的具体有效的操作步骤 算法的复杂度,表示代码的运行效率,用一个大写的O加括号来表示,比如O(1),O(n) 认为算法的复杂度是渐进的,即对于一个大小为n的输入,如果他的 ...

  2. mac安装mysql的两种方法(含配置)

    1.使用安装包安装mysql 双击打开安装文件 双击pkg文件安装 一路向下,记得保存最后弹出框中的密码(它是你mysql root账号的密码) 正常情况下,安装成功. 此时只是安装成功,但还需要额外 ...

  3. Twisted使用和scrapy源码剖析

    1.Twisted是用Python实现的基于事件驱动的网络引擎框架. 事件驱动编程是一种编程范式,这里程序的执行流由外部事件来决定.它的特点是包含一个事件循环,当外部事件发生时使用回调机制来触发相应的 ...

  4. Oracle之 11gR2 RAC 修改监听器端口号的步骤

    Oracle 11gR2 RAC 修改监听器端口号的步骤 说明:192.168.188.181 为public ip1192.168.188.182 为public ip2192.168.188.18 ...

  5. web前端教程:CSS 布局十八般武艺都在这里了

      CSS布局 布局是CSS中一个重要部分,本文总结了CSS布局中的常用技巧,包括常用的水平居中.垂直居中方法,以及单列布局.多列布局的多种实现方式(包括传统的盒模型布局和比较新的flex布局实现), ...

  6. 从Unity中的Attribute到AOP(六)

    本文将重点对Unity剩下常用的Attribute进行讲解,其他不常用的Attribute各位可以自行去官方文档查阅. 首先是UnityEngine命名空间下的. ColorUsage,这个主要作用于 ...

  7. jdk1.8新特性 : 接口中可以有普通方法(非静态方法)和静态方法 , 颠覆了之前我的理解 : 接口中只能有共有常量和抽象方法的概念,后面必须要加一句jdk1.7和1..7之前

    看到jdk某些接口中存在default方法,于是... http://shaomeng95.iteye.com/blog/998820    为什么接口只能是公有常量? public interfac ...

  8. 微信小程序--合法域名校验出错

    第一次做小demo的时候遇到一个问题,合法域名校验出错: 第一步:登陆微信公众号平台--个人中心--设置--开发设置--服务器域名(一个月只有5次修改机会一定要珍惜) 第二步 打开微信开发者工具,有个 ...

  9. java字符串比较

    我最近刚学java,今天编程的时候就遇到一个棘手的问题,就是关于判断两个字符串是否相等的问题.在编程中,通常比较两个字符串是否相同的表达式是"==",但在java中不能这么写.在j ...

  10. [Codeforces 696D] Legen...

    题目大意: 给出一些匹配串,要造一个长度不超过L的字符串,每个匹配串有自己的价值,匹配串每次出现在字符串里都会贡献一次价值...要求可能得到的最大价值. 匹配串总长不超200,L<=10^14, ...