开启请求缓存

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

  1. package org.hope.hystrix.example.request.cache;
  2.  
  3. import com.netflix.hystrix.HystrixCommand;
  4. import com.netflix.hystrix.HystrixCommandGroupKey;
  5.  
  6. public class CommandUsingRequestCache extends HystrixCommand<Boolean> {
  7. private final int value;
  8.  
  9. public CommandUsingRequestCache(int value) {
  10. super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
  11. this.value = value;
  12. }
  13.  
  14. @Override
  15. protected Boolean run() throws Exception {
  16. return value == 0 || value % 2 == 0;
  17. }
  18.  
  19. @Override
  20. protected String getCacheKey() {
  21. return String.valueOf(value);
  22. }
  23. }

单元测试

  1. package org.hope.hystrix.example.request.cache;
  2.  
  3. import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
  4. import org.hope.hystrix.example.request.cache.CommandUsingRequestCache;
  5. import org.junit.Test;
  6.  
  7. import static org.junit.Assert.assertEquals;
  8. import static org.junit.Assert.assertFalse;
  9. import static org.junit.Assert.assertTrue;
  10.  
  11. public class CommandUsingRequestCacheTest {
  12.  
  13. @Test
  14. public void testWithoutCacheHits() {
  15. HystrixRequestContext cxt = HystrixRequestContext.initializeContext();
  16. try {
  17. assertTrue(new CommandUsingRequestCache(2).execute());
  18. assertTrue(new CommandUsingRequestCache(1).execute());
  19. } finally {
  20. cxt.shutdown();
  21. }
  22. }
  23.  
  24. @Test
  25. public void testWithCacheHits() {
  26. HystrixRequestContext cxt = HystrixRequestContext.initializeContext();
  27. try {
  28. CommandUsingRequestCache command2a = new CommandUsingRequestCache(2);
  29. CommandUsingRequestCache command2b = new CommandUsingRequestCache(2);
  30.  
  31. assertTrue(command2a.execute());
  32. // this is the first time we've executed this command with the value of "2" so it should not be from cache
  33. // assertFalse(command2a.isResponseFromCache());
  34. System.out.println(command2a.isResponseFromCache());
  35.  
  36. assertTrue(command2b.execute());
  37. // this is the second time we've executed this command with the same value so it should return from cache
  38. // assertTrue(command2b.isResponseFromCache());
  39. System.out.println(command2b.isResponseFromCache());
  40. } finally {
  41. cxt.shutdown();
  42. }
  43.  
  44. // start a new request context
  45. cxt = HystrixRequestContext.initializeContext();
  46. try {
  47. CommandUsingRequestCache command3b = new CommandUsingRequestCache(2);
  48. assertTrue(command3b.execute());
  49. // this is a new request context so this should not come from cache
  50. // assertFalse(command3b.isResponseFromCache());
  51. System.out.println(command3b.isResponseFromCache());
  52. } finally {
  53. cxt.shutdown();
  54. }
  55. }
  56. }

清理失效缓存

  1. package org.hope.hystrix.example.request.cache;
  2.  
  3. import com.netflix.hystrix.HystrixCommand;
  4. import com.netflix.hystrix.HystrixCommandGroupKey;
  5. import com.netflix.hystrix.HystrixCommandKey;
  6. import com.netflix.hystrix.HystrixRequestCache;
  7. import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategyDefault;
  8.  
  9. /**
  10. * 清理缓存
  11. */
  12. public class CommandUsingRequestCacheInvalidation{
  13.  
  14. private static volatile String prefixStoredOnRemoteDataStore = "ValueBeforeSet_";
  15.  
  16. public static class GetterCommand extends HystrixCommand<String> {
  17. private static final HystrixCommandKey GETTER_KEY = HystrixCommandKey.Factory.asKey("GetterCommand");
  18. private final int id;
  19. public GetterCommand(int id) {
  20. super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("GetSetGet")).andCommandKey(GETTER_KEY));
  21. this.id = id;
  22. }
  23.  
  24. @Override
  25. protected String run() throws Exception {
  26. return prefixStoredOnRemoteDataStore + id;
  27. }
  28.  
  29. @Override
  30. protected String getCacheKey() {
  31. return String.valueOf(id);
  32. }
  33.  
  34. //Allow the cache to be flushed for this object.
  35. public static void flushCache(int id) {
  36. HystrixRequestCache.getInstance(GETTER_KEY, HystrixConcurrencyStrategyDefault.getInstance()).clear(String.valueOf(id));
  37. }
  38.  
  39. }
  40.  
  41. public static class SetterCommand extends HystrixCommand<Void> {
  42. private final int id;
  43. private final String prefix;
  44.  
  45. public SetterCommand(int id, String prefix) {
  46. super(HystrixCommandGroupKey.Factory.asKey("GetSetGet"));
  47. this.id = id;
  48. this.prefix = prefix;
  49. }
  50.  
  51. @Override
  52. protected Void run() throws Exception {
  53. // persist the value against the datastore
  54. prefixStoredOnRemoteDataStore = prefix;
  55. // flush the cache
  56. GetterCommand.flushCache(id);
  57. return null;
  58. }
  59. }
  60.  
  61. }

单元测试:

  1. package org.hope.hystrix.example.request.cache;
  2.  
  3. import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
  4. import org.junit.Test;
  5.  
  6. /**
  7. * Created by lisen on 2017/12/27.
  8. */
  9. public class CommandUsingRequestCacheInvalidationTest {
  10.  
  11. @Test
  12. public void flushCacheTest() {
  13. HystrixRequestContext context = HystrixRequestContext.initializeContext();
  14. System.out.println(new CommandUsingRequestCacheInvalidation.GetterCommand(1).execute());
  15.  
  16. CommandUsingRequestCacheInvalidation.GetterCommand commandAgainstCache = new CommandUsingRequestCacheInvalidation.GetterCommand(1);
  17.  
  18. System.out.println(commandAgainstCache.isResponseFromCache()); //false
  19. System.out.println(commandAgainstCache.execute());
  20. System.out.println(commandAgainstCache.isResponseFromCache()); //false
  21. // set the new value
  22. new CommandUsingRequestCacheInvalidation.SetterCommand(1, "ValueAfterSet_").execute();
  23. // fetch it again
  24. CommandUsingRequestCacheInvalidation.GetterCommand commandAfterSet = new CommandUsingRequestCacheInvalidation.GetterCommand(1);
  25. //the getter should return with the new prefix, not the value from cache
  26. System.out.println(commandAfterSet.isResponseFromCache());
  27. System.out.println(commandAfterSet.execute());
  28. }
  29. }

注解的实现请求缓存

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

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

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

value

设置缓存

  1. package org.hope.hystrix.example.request.cache;
  2.  
  3. import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
  4. import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheKey;
  5. import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheResult;
  6. import org.hope.hystrix.example.model.User;
  7. import org.springframework.stereotype.Service;
  8. @Service
  9. public class RequestCacheAnnotation {
  10.  
  11. /**
  12. * 返回的结果会置入请求缓存中,缓存的key值会使用所有的方法入参,
  13. * 也就是这里Long类型的id
  14. */
  15. @CacheResult
  16. @HystrixCommand
  17. public String getUserById(Long id) {
  18. return "你好" + id;
  19. }
  20.  
  21. /**
  22. * cacheKeyMethod可以为缓存指定具体的缓存key
  23. */
  24. @CacheResult(cacheKeyMethod = "getUserByIdCacheKey")
  25. @HystrixCommand
  26. public String getUserById2(Long id) {
  27. return "你好:" + id;
  28. }
  29.  
  30. public String getUserByIdCacheKey(Long id) {
  31. return String.valueOf(id);
  32. }
  33.  
  34. /**
  35. * 通过@CacheKey来定义具体的缓存Key。
  36. * 但是注意,@CacheKey的优先级比@CacheResult(cacheKeyMethod = "")的优先级低。
  37. * 如果已经使用了cacheKeyMethod指定缓存Key的生成函数,那么@CacheKey注解不会生效
  38. */
  39. @CacheResult
  40. @HystrixCommand
  41. public String getUserById3(@CacheKey("id") Long id) {
  42. return "你好:" + id;
  43. }
  44.  
  45. /**
  46. * @CacheKey还可以通过访问参数对象内部属性作为缓存key
  47. * 这里指定了User对象id属性作为缓存key
  48. */
  49. @CacheResult
  50. @HystrixCommand
  51. public String getUserById4(@CacheKey("id") User user) {
  52. return "你好" + user.getId();
  53. }
  54.  
  55. }

清理缓存

  1. package org.hope.hystrix.example.request.cache;
  2.  
  3. import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
  4. import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheKey;
  5. import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheRemove;
  6. import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheResult;
  7. import org.hope.hystrix.example.model.User;
  8.  
  9. public class RequestClearCacheAnnotation {
  10.  
  11. @CacheResult
  12. @HystrixCommand
  13. public User getUserById(@CacheKey("id") Long id) {
  14. User u = new User();
  15. u.setId(id);
  16. return u;
  17. }
  18.  
  19. /**
  20. * 用@CacheRemove来清理失效缓存,其中commandKey是必须指定的
  21. */
  22. @CacheRemove(commandKey = "getUserById")
  23. @HystrixCommand
  24. public void update(@CacheKey("id") User user) {
  25. User u = new User();
  26. u.setId(20L);
  27. }
  28.  
  29. public String getUserById(User user) {
  30. return String.valueOf(user.getId());
  31. }
  32. }

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. 2017春 前端自动化(二) 页面自动刷新、sass与css转换的使用、pxToRem直观转换

    2017春 前端自动化(二)   页面自动刷新.sass与css转换的使用.pxToRem直观转换 引言:   此文要演示:浏览器页面自动刷新:移动端px与rem的转换,简单直观化:使用sass自动生 ...

  2. 【费用流】BZOJ1061: [Noi2008]志愿者招募(这题超好)

    1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 5291  Solved: 3173[Submit][Stat ...

  3. C语言循环的实现

    在C语言中采用3中语法来实现循环,它们分别是while.for.do while,本文将分别说明这三种循环的实现,并对它们的运行效率进行比较. do while 首先来看do while的实现:下面是 ...

  4. sql servel 报错:将 expression 转换为数据类型 int 时出现算术溢出错误。

    执行sql语句:SELECT   AVG( DATEDIFF(s,s.CreatedDate,s.SendDate)  ) AS submitTime FROM dbo.SmsSend AS s    ...

  5. ionic滑动框 ---轮播图(ion-slide-box) 的使用

    1. html : <ion-slide-box auto-play="true" slide-interval=3000 show-pager="false&qu ...

  6. 使用神经网络来拟合函数y = x^3 +b

    我们使用一个三层的小网络来,模拟函数y = x^3+b函数 import tensorflow as tf import numpy as np import matplotlib.pyplot as ...

  7. Java入门篇(一)——如何编写一个简单的Java程序

    最近准备花费很长一段时间写一些关于Java的从入门到进阶再到项目开发的教程,希望对初学Java的朋友们有所帮助,更快的融入Java的学习之中. 主要内容包括JavaSE.JavaEE的基础知识以及如何 ...

  8. linux(五)之vi编译器

    前面介绍了linux的常用命令和对文本的操作,接下来我将对大家领略一下vi编译器的强大功能.希望大家觉得写的还不错的话可以点个“推荐”哦! 一.vim/vi编译器简介 Vim/Vi是一个功能强大的全屏 ...

  9. TSP(个人模版)

    O(n^2)TSP: #include<stdio.h> #include<string.h> #include<algorithm> #include<io ...

  10. vijos 1213:80人环游世界

    描述 想必大家都看过成龙大哥的<80天环游世界>,里面的紧张刺激的打斗场面一定给你留下了深刻的印象.现在就有这么一个80人的团伙,也想来一次环游世界. 他们打算兵分多路,游遍每一个国家. ...