Hystrix-request cache(请求缓存)
开启请求缓存
请求缓存在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(请求缓存)的更多相关文章
- hystrix中request cache请求缓存
有一个概念,叫做reqeust context,请求上下文,一般来说,在一个web应用中, 我们会在一个filter里面,对每一个请求都施加一个请求上下文,就是说,tomcat容器内,每一次请求,就是 ...
- SpringCloud实战-Hystrix线程隔离&请求缓存&请求合并
接着上一篇的Hystrix进行进一步了解. 当系统用户不断增长时,每个微服务需要承受的并发压力也越来越大,在分布式环境中,通常压力来自对依赖服务的调用,因为亲戚依赖服务的资源需要通过通信来实现,这样的 ...
- SpringCloud实战4-Hystrix线程隔离&请求缓存&请求合并
接着上一篇的Hystrix进行进一步了解. 当系统用户不断增长时,每个微服务需要承受的并发压力也越来越大,在分布式环境中,通常压力来自对依赖服务的调用,因为亲戚依赖服务的资源需要通过通信来实现,这样的 ...
- Spring-cloud (八) Hystrix 请求缓存的使用
前言: 最近忙着微服务项目的开发,脱更了半个月多,今天项目的初版已经完成,所以打算继续我们的微服务学习,由于Hystrix这一块东西好多,只好多拆分几篇文章写,对于一般对性能要求不是很高的项目中,可以 ...
- hystrix源码之请求缓存
HystrixRequestCache 请求缓存.内部是一个静态ConcurrentHashMap存储各个命令的缓存器,RequestCacheKey为key,HystrixRequestCache为 ...
- Hystrix框架5--请求缓存和collapser
简介 在Hystrix中有个Request的概念,有一些操作需要在request中进行 缓存 在Hystrix调用服务时,如果只是查询接口,可以使用缓存进行优化,从而跳过真实访问请求. 应用 需要启用 ...
- Spring Cloud(Dalston.SR5)--Hystrix 断路器-合并请求
在 Spring Cloud 中可以使用注解的方式来支持 Hystrix 的合并请求,缓存与合并请求功能需要先初始化请求上下文才能实现,因此,必须实现 javax.servlet.Filter 用于创 ...
- http cache & 浏览器缓存,存储位置的优先级,条件?
http cache & 浏览器缓存,存储位置的优先级,条件? memory cache disk cache 浏览器缓存,存储位置的优先级,条件, 机制,原理是什么? from memory ...
- 利用LRU策略实现Axios请求缓存
业务场景 前一段时间刚做完一个项目,先说一下业务场景,有别于其他的前端项目,这次的项目是直接调用第三方服务的接口,而我们的服务端只做鉴权和透传,第三方为了灵活,把接口拆的很零散,所以这个项目就像扔给你 ...
随机推荐
- 2017春 前端自动化(二) 页面自动刷新、sass与css转换的使用、pxToRem直观转换
2017春 前端自动化(二) 页面自动刷新.sass与css转换的使用.pxToRem直观转换 引言: 此文要演示:浏览器页面自动刷新:移动端px与rem的转换,简单直观化:使用sass自动生 ...
- 【费用流】BZOJ1061: [Noi2008]志愿者招募(这题超好)
1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 5291 Solved: 3173[Submit][Stat ...
- C语言循环的实现
在C语言中采用3中语法来实现循环,它们分别是while.for.do while,本文将分别说明这三种循环的实现,并对它们的运行效率进行比较. do while 首先来看do while的实现:下面是 ...
- sql servel 报错:将 expression 转换为数据类型 int 时出现算术溢出错误。
执行sql语句:SELECT AVG( DATEDIFF(s,s.CreatedDate,s.SendDate) ) AS submitTime FROM dbo.SmsSend AS s ...
- ionic滑动框 ---轮播图(ion-slide-box) 的使用
1. html : <ion-slide-box auto-play="true" slide-interval=3000 show-pager="false&qu ...
- 使用神经网络来拟合函数y = x^3 +b
我们使用一个三层的小网络来,模拟函数y = x^3+b函数 import tensorflow as tf import numpy as np import matplotlib.pyplot as ...
- Java入门篇(一)——如何编写一个简单的Java程序
最近准备花费很长一段时间写一些关于Java的从入门到进阶再到项目开发的教程,希望对初学Java的朋友们有所帮助,更快的融入Java的学习之中. 主要内容包括JavaSE.JavaEE的基础知识以及如何 ...
- linux(五)之vi编译器
前面介绍了linux的常用命令和对文本的操作,接下来我将对大家领略一下vi编译器的强大功能.希望大家觉得写的还不错的话可以点个“推荐”哦! 一.vim/vi编译器简介 Vim/Vi是一个功能强大的全屏 ...
- TSP(个人模版)
O(n^2)TSP: #include<stdio.h> #include<string.h> #include<algorithm> #include<io ...
- vijos 1213:80人环游世界
描述 想必大家都看过成龙大哥的<80天环游世界>,里面的紧张刺激的打斗场面一定给你留下了深刻的印象.现在就有这么一个80人的团伙,也想来一次环游世界. 他们打算兵分多路,游遍每一个国家. ...