千家信息网

Spring Cloud中Hystrix的请求缓存怎么实现

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,本篇内容介绍了"Spring Cloud中Hystrix的请求缓存怎么实现"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细
千家信息网最后更新 2026年10月31日Spring Cloud中Hystrix的请求缓存怎么实现

本篇内容介绍了"Spring Cloud中Hystrix的请求缓存怎么实现"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

通过方法重载开启缓存

如果我们使用了自定义Hystrix请求命令的方式来使用Hystrix,那么我们只需要重写getCacheKey方法即可实现请求缓存,如下:

public class BookCommand extends HystrixCommand {    private RestTemplate restTemplate;    private Long id;    @Override    protected Book getFallback() {        Throwable executionException = getExecutionException();        System.out.println(executionException.getMessage());        return new Book("宋诗选注", 88, "钱钟书", "三联书店");    }    @Override    protected Book run() throws Exception {        return restTemplate.getForObject("http://HELLO-SERVICE/getbook5/{1}", Book.class,id);    }    public BookCommand(Setter setter, RestTemplate restTemplate,Long id) {        super(setter);        this.restTemplate = restTemplate;        this.id = id;    }    @Override    protected String getCacheKey() {        return String.valueOf(id);    }}

系统在运行时会根据getCacheKey方法的返回值来判断这个请求是否和之前执行过的请求一样,即被缓存,如果被缓存,则直接使用缓存数据而不去请求服务提供者,那么很明显,getCacheKey方法将在run方法之前执行。我现在在服务提供者中打印一个日志,如下:

@RequestMapping(value = "/getbook5/{id}", method = RequestMethod.GET)public Book book5(@PathVariable("id") Integer id) {    System.out.println(">>>>>>>>/getbook5/{id}");    if (id == 1) {        return new Book("《李自成》", 55, "姚雪垠", "人民文学出版社");    } else if (id == 2) {        return new Book("中国文学简史", 33, "林庚", "清华大学出版社");    }    return new Book("文学改良刍议", 33, "胡适", "无");}

然后我们服务消费者的Controller中来执行这个请求,如下:

@RequestMapping("/test5")public Book test5() {    HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey("commandKey");    HystrixRequestContext.initializeContext();    BookCommand bc1 = new BookCommand(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("")).andCommandKey(commandKey), restTemplate, 1l);    Book e1 = bc1.execute();    BookCommand bc2 = new BookCommand(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("")).andCommandKey(commandKey), restTemplate, 1l);    Book e2 = bc2.execute();    BookCommand bc3 = new BookCommand(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("")).andCommandKey(commandKey), restTemplate, 1l);    Book e3 = bc3.execute();    System.out.println("e1:" + e1);    System.out.println("e2:" + e2);    System.out.println("e3:" + e3);    return e1;}

我连着发起三个相同的请求,我们来看看服务提供者的日志打印情况,注意,在服务请求发起之前,需要先初始化HystrixRequestContext。执行效果如下:

小伙伴们看到,上面是服务提供者打印出来的日志,下面是服务消费者打印出来的日志,发起了三个请求,但是服务提供者实际上只执行了一次,其他两次都使用了缓存数据。

有一种特殊的情况:如果我将服务提供者的数据修改了,那么缓存的数据就应该被清除,否则用户在读取的时候就有可能获取到一个错误的数据,缓存数据的清除也很容易,也是根据id来清除,方式如下:

@RequestMapping("/test5")public Book test5() {    HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey("commandKey");    HystrixRequestContext.initializeContext();    BookCommand bc1 = new BookCommand(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("")).andCommandKey(commandKey), restTemplate, 1l);    Book e1 = bc1.execute();    HystrixRequestCache.getInstance(commandKey, HystrixConcurrencyStrategyDefault.getInstance()).clear(String.valueOf(1l));    BookCommand bc2 = new BookCommand(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("")).andCommandKey(commandKey), restTemplate, 1l);    Book e2 = bc2.execute();    BookCommand bc3 = new BookCommand(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("")).andCommandKey(commandKey), restTemplate, 1l);    Book e3 = bc3.execute();    System.out.println("e1:" + e1);    System.out.println("e2:" + e2);    System.out.println("e3:" + e3);    return e1;}

小伙伴们注意,这里我们执行完第一次请求之后,id为1的数据就已经被缓存下来了,然后我通过HystrixRequestCache中的clear方法将缓存的数据清除掉,这个时候如果我再发起请求,则又会调用服务提供者的方法,我们来看一下执行结果,如下:

小伙伴们看到,此时服务提供者的方法执行了两次,因为我在第一次请求结束后将id为1的缓存清除了。

通过注解开启缓存

当然,我们也可以通过注解来开启缓存,和缓存相关的注解一共有三个,分别是@CacheResult、@CacheKey和@CacheRemove,我们分别来看。

@CacheResult

@CacheResult方法可以用在我们之前的Service方法上,表示给该方法开启缓存,默认情况下方法的所有参数都将作为缓存的key,如下:

@CacheResult@HystrixCommandpublic Book test6(Integer id,String aa) {    return restTemplate.getForObject("http://HELLO-SERVICE/getbook5/{1}", Book.class, id);}

此时test6方法会自动开启缓存,默认所有的参数都将作为缓存的key,如果在某次调用中传入的两个参数和之前传入的两个参数都一致的话,则直接使用缓存,否则就发起请求,如下:

@RequestMapping("/test6")public Book test6() {    HystrixRequestContext.initializeContext();    //第一次发起请求    Book b1 = bookService.test6(2, "");    //参数和上次一致,使用缓存数据    Book b2 = bookService.test6(2, "");    //参数不一致,发起新请求    Book b3 = bookService.test6(2, "aa");    return b1;}

当然这里我们也可以在@CacheResult中添加cacheKeyMethod属性来指定返回缓存key的方法,注意返回的key要是String类型的,如下:

@CacheResult(cacheKeyMethod = "getCacheKey2")@HystrixCommandpublic Book test6(Integer id) {    return restTemplate.getForObject("http://HELLO-SERVICE/getbook5/{1}", Book.class, id);}public String getCacheKey2(Integer id) {    return String.valueOf(id);}

此时默认的规则失效。

@CacheKey

当然除了使用默认数据之外,我们也可以使用@CacheKey来指定缓存的key,如下:

@CacheResult@HystrixCommandpublic Book test6(@CacheKey Integer id,String aa) {    return restTemplate.getForObject("http://HELLO-SERVICE/getbook5/{1}", Book.class, id);}

这里我们使用@CacheKey注解指明了缓存的key为id,和aa这个参数无关,此时只要id相同就认为是同一个请求,而aa参数的值则不会作为判断缓存的依据(这里只是举例子,实际开发中我们的调用条件可能都要作为key,否则可能会获取到错误的数据)。如果我们即使用了@CacheResult中cacheKeyMethod属性来指定key,又使用了@CacheKey注解来指定key,则后者失效。

@CacheRemove

这个当然是用来让缓存失效的注解,用法也很简单,如下:

@CacheRemove(commandKey = "test6")@HystrixCommandpublic Book test7(@CacheKey Integer id) {    return null;}

注意这里必须指定commandKey,commandKey的值就为缓存的位置,配置了commandKey属性的值,Hystrix才能找到请求命令缓存的位置。举个简单的例子,如下:

@RequestMapping("/test6")public Book test6() {    HystrixRequestContext.initializeContext();    //第一次发起请求    Book b1 = bookService.test6(2);    //清除缓存    bookService.test7(2);    //缓存被清除,重新发起请求    Book b2 = bookService.test6(2);    //参数一致,使用缓存数据    Book b3 = bookService.test6(2);    return b1;}

"Spring Cloud中Hystrix的请求缓存怎么实现"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

缓存 方法 数据 服务 参数 提供者 注解 一致 情况 日志 第一次 三个 实际 小伙 小伙伴 属性 文学 相同 两个 位置 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技公司 南京欣网互联网络科技 保险科技 互联网保险 朗新科技与工业互联网 互联网科技金融公司 平安科技 互联网 迪茉互联网科技 深圳天众互联网科技公司 广州善班互联网科技 互联网科技咨询 银川新华互联网科技学校地址 温州喔噻互联网科技有限公司 厦门千工互联网科技有限公司 黑科技 体验场景 互联网大会 银行科技岗属于互联网吗 扫呗互联网科技有限公司 山东蛋芒互联网科技有限公司 杭州科技互联网公司有哪些 广东猫王互联网科技有限公司电话 东风日产互联网科技公司叫什么 深圳恒合互联网络科技有限公司 合肥互联网科技公司 苏州互联网科技贷款公司 互联网科技logo 伴你行互联网科技有限公司 深圳艾佳互联网科技 厦门比较好的科技互联网公司 山东星卡互联网科技有限公司官网 深圳互联网科技的发展 福仕德教育科技互联网
0