hystrix基于request cache请求缓存技术优化批量数据查询接口
1、创建command,2种command类型
2、执行command,4种执行方式
3、查找是否开启了request cache,是否有请求缓存,如果有缓存,直接取用缓存,返回结果
首先,有一个概念,叫做reqeust context,请求上下文,一般来说,在一个web应用中,hystrix
我们会在一个filter里面,对每一个请求都施加一个请求上下文,就是说,tomcat容器内,每一次请求,就是一次请求上下文
然后在这次请求上下文中,我们会去执行N多代码,调用N多依赖服务,有的依赖服务可能还会调用好几次
在一次请求上下文中,如果有多个command,参数都是一样的,调用的接口也是一样的,其实结果可以认为也是一样的
那么这个时候,我们就可以让第一次command执行,返回的结果,被缓存在内存中,然后这个请求上下文中,后续的其他对这个依赖的调用全部从内存中取用缓存结果就可以了
不用在一次请求上下文中反复多次的执行一样的command,提升整个请求的性能
HystrixCommand和HystrixObservableCommand都可以指定一个缓存key,然后hystrix会自动进行缓存,接着在同一个request context内,再次访问的时候,就会直接取用缓存
用请求缓存,可以避免重复执行网络请求
多次调用一个command,那么只会执行一次,后面都是直接取缓存
对于请求缓存(request caching),请求合并(request collapsing),请求日志(request log),等等技术,都必须自己管理HystrixReuqestContext的声明周期
在一个请求执行之前,都必须先初始化一个request context
HystrixRequestContext context = HystrixRequestContext.initializeContext();
然后在请求结束之后,需要关闭request context
context.shutdown();
一般来说,在java web来的应用中,都是通过filter过滤器来实现的
public class HystrixRequestContextServletFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HystrixRequestContext context = HystrixRequestContext.initializeContext();
try {
chain.doFilter(request, response);
} finally {
context.shutdown();
}
}
}
@Bean
public FilterRegistrationBean indexFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean(new IndexFilter());
registration.addUrlPatterns("/");
return registration;
}
结合咱们的业务背景,我们做了一个批量查询商品数据的接口,在这个里面,我们其实通过HystrixObservableCommand一次性批量查询多个商品id的数据
但是这里有个问题,如果说nginx在本地缓存失效了,重新获取一批缓存,传递过来的productId都没有进行去重,1,1,2,2,5,6,7
那么可能说,商品id出现了重复,如果按照我们之前的业务逻辑,可能就会重复对productId=1的商品查询两次,productId=2的商品查询两次
我们对批量查询商品数据的接口,可以用request cache做一个优化,就是说一次请求,就是一次request context,对相同的商品查询只能执行一次,其余的都走request cache
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;
}
@Override
protected String getCacheKey() {
return String.valueOf(value);
}
}
@Test
public void testWithCacheHits() {
HystrixRequestContext context = 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());
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());
} finally {
context.shutdown();
}
// start a new request context
context = 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());
} finally {
context.shutdown();
}
}
缓存的手动清理
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);
}
/**
* Allow the cache to be flushed for this object.
*
* @param id
* argument that would normally be passed to the command
*/
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() {
// persist the value against the datastore
prefixStoredOnRemoteDataStore = prefix;
// flush the cache
GetterCommand.flushCache(id);
// no return value
return null;
}
}
hystrix基于request cache请求缓存技术优化批量数据查询接口相关推荐
- Hystrix面试 - 基于 request cache 请求缓存技术优化批量商品数据查询接口
Hystrix面试 - 基于 request cache 请求缓存技术优化批量商品数据查询接口 Hystrix command 执行时 8 大步骤第三步,就是检查 Request cache 是否有缓 ...
- vue获取商品数据接口_基于 request cache 请求缓存技术优化批量商品数据查询接口...
Hystrix command 执行时 8 大步骤第三步,就是检查 Request cache 是否有缓存. 首先,有一个概念,叫做 Request Context 请求上下文,一般来说,在一个 we ...
- 另类的缓存技术(存储数据)
代码 1 using System; 2 using System.Web; 3 using System.Web.Caching; 4 5 namespace Mysoft.Cache ...
- 基于PHP后台请求亚马逊订单列表listOrder接口
参阅:(接口调试工具) https://mws.amazonservices.com/scratchpad/index.html 参阅2:(API文档) http://docs.developer.a ...
- SpringCloud实战4-Hystrix线程隔离请求缓存请求合并
接着上一篇的Hystrix进行进一步了解. 当系统用户不断增长时,每个微服务需要承受的并发压力也越来越大,在分布式环境中,通常压力来自对依赖服务的调用,因为亲戚依赖服务的资源需要通过通信来实现,这样的 ...
- ASP.NET Core 缓存技术 及 Nginx 缓存配置
前言 在Asp.Net Core Nginx部署一文中,主要是讲述的如何利用Nginx来实现应用程序的部署,使用Nginx来部署主要有两大好处,第一是利用Nginx的负载均衡功能,第二是使用Nginx ...
- 分布式数据流计算系统的数据缓存技术综述
点击上方蓝字关注我们 分布式数据流计算系统的数据缓存技术综述 袁旭初, 付国, 毕继泽, 张岩峰, 聂铁铮, 谷峪, 鲍玉斌, 于戈 东北大学计算机科学与工程学院,辽宁 沈阳 110169 论文引用格 ...
- L1 Cache(一级缓存)
CPU缓存(Cache Memory)是位于CPU与内存之间的临时存储器,它的容量比内存小的多但是交换速度却比内存要快得多.缓存的出现主要是为了解决CPU运算速度与内存读写速度不匹配的矛盾,因为CPU ...
- 后端系统缓存技术分析
缓存有很多种,如CPU 缓存.磁盘缓存.浏览器缓存等:本文主要针对后端系统的缓存,也就是将程序或系统经常要使用的对象存在内存中,以便在使用时可以快速调用,避免加载数据或者创建重复的实例,以达到减少系统 ...
最新文章
- 畅销书《简明的TensorFlow2》作者李卓桓开讲啦!
- 十天精通CSS3学习笔记 part2
- python中调用多进程加速处理文件
- python编程*三角形图形创意图片_python循环输出三角形图案的例子
- Faster R-CNN 英文论文翻译笔记
- Android虚拟机和Java虚拟机的区别
- cypress测试脚本_Cypress 自动化测试学习使用
- Pandas DataFrame索引和列属性
- 云数据库MySQL的发展史
- 多线程常见面试题(含常见项目遇到多线程问题解决及面试对话)
- springboot基于微信小程序的校园体育运动场地及器材租凭系统设计与实现毕业设计源码131052
- vip html代码,vip.html
- android 专业密码键盘,Android仿支付宝、京东的密码键盘和输入框
- 招银网络2018笔试分享
- 路由器接口配置与管理——6
- 四阶龙格-库塔法求解常微分方程的初值问题
- 修改so文件的关键方法
- win10 装黑苹果 完整教程
- 人工智能,达尔文进化论
- 单接口测试(场景测试)
热门文章
- 【Java并发性和多线程】Java中的锁
- Fragment过度动画分析一
- AD RMS 问题解决 事件ID:139
- 浅谈Java中的各种锁
- 用java做一个管理系统难吗_想知道怎样用Java做出一个学生管理系统,课一直听得一知半解。现在考试啥都不会?...
- androidq获取文件正式路径_android Q 新特性
- 03 | 事务隔离:为什么你改了我还看不见?笔记(转)
- window.opener.location.reload() and href()的区别
- 框架源码专题:Spring的事件监听、发布机制 ApplicationListener
- 安装虚拟机Centos系统并安装Docker过程记录