在 Spring Cloud 中可以使用注解的方式来支持 Hystrix 的缓存,缓存与合并请求功能需要先初始化请求上下文才能实现,因此,必须实现 javax.servlet.Filter 用于创建和销毁 Hystrix 的请求上下文,而缓存的注解有 @CacheResult、@CacheRemove,@CacheResult 注解必须和 @HystrixCommand 注解一起使用,示例如下:

  • 创建 Filter

    在 Filter 初始化时就创建 HystrixRequestContext,然后在每个请求调用 doFilter 方法时,将初始化的上下文赋值到当前线程存储,这样就能在全局使用 Hystrix 的缓存和合并请求

    package org.lixue;

     
     

    import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;

     
     

    import javax.servlet.*;

    import javax.servlet.annotation.WebFilter;

    importj ava.io.IOException;

     
     

    @WebFilter(urlPatterns="/*",filterName="HystrixRequestContextFilter")

    public class HystrixRequestContextFilter implements Filter{

    HystrixRequestContext context=null;

     
     

    @Override

    public void init(FilterConfig filterConfig) throws ServletException{

    context=HystrixRequestContext.initializeContext();

    }

     
     

    @Override

    publicvoid doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException{

    HystrixRequestContext.setContextOnCurrentThread(context);

    try{

    chain.doFilter(request,response);

    }catch(Exceptionex){

    ex.printStackTrace();

    }

    }

     
     

    @Override

    publicvoiddestroy(){

    if(context!=null){

    context.shutdown();

    }

    }

    }

     
     

  • 创建服务调用

    注解 @CacheResult 必须和 @HystrixCommand 同时使用,@CacheResult 注解的 cacheKeyMethod 参数指定的方法必须和 @CacheResult 标注的方法参数一致,并且相同参数产生的 key 值应该一致;

    如果数据存在修改,则必须使用 @CacheRemove 注解标注修改方法,同样也需要指定 cacheKeyMethod 参数,表示需要移除缓存的 key,其 commandKey 参数也必须指定和 @HystrixCommand 注解的 commandKey 值一致;

    如果不指定 @CacheResult 和 @CacheRemove 注解的 cacheKeyMethod 参数,也可使用 @CacheKey 注解来标注方法的参数,表示使用方法的参数来作为缓存 key

    package org.lixue;

     
     

    import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

    import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;

    import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheRemove;

    import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheResult;

    import org.springframework.beans.factory.annotation.Autowired;

    import org.springframework.stereotype.Component;

    import org.springframework.web.client.RestTemplate;

     
     

    @Component

    public class HelloWorldClient{

     
     

    @Autowired

    private RestTemplate restTemplate;

     
     

    @HystrixCommand(fallbackMethod="speakFallback",commandKey="hello-world",

    threadPoolKey="hello-world",groupKey="hello-world",

    commandProperties={

    @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="500")

    },

    threadPoolProperties={

    @HystrixProperty(name="coreSize",value="50")

    }

    )

    @CacheResult(cacheKeyMethod="speakCacheKey")

    public String speak(String name){

    if(name==null||"".equals(name)){

    name="null";

    }

    return restTemplate.getForObject("http://HELLOWORLD-PROVIDER/speaks?names="+name,String.class);

    }

     
     

    /**

    *生成speak方法的缓存Key

    *

    *@param name

    *@return

    */

    private String speakCacheKey(String name){

    return"speak."+name;

    }

     
     

    /**

    *修改speak数据,移除缓存

    *

    *@param name

    *@return

    */

    @CacheRemove(commandKey="hello-world",cacheKeyMethod="speakCacheKey")

    public String updateSpeak(String name){

    return name;

    }

     
     

    /**

    *speak返回的回退方法

    *

    *@param name

    *@return

    */

    private String speakFallback(String name){

    return"call error,name is"+name;

    }

    }

  • 服务增加日志

    @RequestMapping(method=RequestMethod.GET,name="speak",path="/speaks",

    produces=MediaType.APPLICATION_JSON_UTF8_VALUE)

    public Map<String,String> speaks(@RequestParam(value="names")String names) throws InterruptedException{

    System.out.println("speaksnames="+names);

    Map<String,String>map=newHashMap<>();

    if(names==null||"".equals(names)){

    return map;

    }

     
     

    String[] splitName=names.split(",");

    for(Stringname:splitName){

    map.put(name,"HelloWorld"+name+"Port="+port);

    }

    return map;

    }

     
     

  • 测试验证

    由于我们使用了 Ribbon 因此首先启动 eureka-server 和 service-provider 服务,然后启动该项目,访问 http://localhost:8077/speak?name=abc 可以看到能正常返回信息,如下:

    {"abc":"Hello World abc Port=8002"}

    服务输出日志:

    speaks names=abc

    多次刷新,可以看到服务的日志只显示了一次,表示后续的刷新访问都是使用的 Hystrix 缓存。

     
     

     
     

     
     

Spring Cloud(Dalston.SR5)--Hystrix 断路器-缓存的更多相关文章

  1. Spring Cloud(Dalston.SR5)--Hystrix 断路器

    Spring Cloud 对 Hystrix 进行了封装,使用 Hystrix 是通过 @HystrixCommand 注解来使用的,被 @HystrixCommand 注解标注的方法,会使用 Asp ...

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

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

  3. Spring Cloud(Dalston.SR5)--Hystrix 监控

    在服务调用者加入 Actuator ,可以对服务调用者的健康情况进行实时监控,例如,断路器是否打开.当前负载情况等. 服务调用者 需要增加 actuator依赖, 修改 POM.xml 中增加以下依赖 ...

  4. Spring Cloud入门教程-Hystrix断路器实现容错和降级

    简介 Spring cloud提供了Hystrix容错库用以在服务不可用时,对配置了断路器的方法实行降级策略,临时调用备用方法.这篇文章将创建一个产品微服务,注册到eureka服务注册中心,然后我们使 ...

  5. Spring Cloud(Dalston.SR5)--Feign 与 Hystrix 断路器整合

    创建项目 要使 Feign 与 Hystrix 进行整合,我们需要增加 Feign 和 Hystrix 的依赖,修改 POM.xml 中增加以下依赖项如下: <?xmlversion=" ...

  6. Spring Cloud(Dalston.SR5)--Config 集群配置中心-刷新配置

    远程 SVN 服务器上面的配置修改后,需要通知客户端来改变配置,需要增加 spring-boot-starter-actuator 依赖并将 management.security.enabled 设 ...

  7. Spring Cloud(Dalston.SR5)--Config 集群配置中心

    Spring Cloud Config 是一个全新的项目,用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持,他分为服务端和客户端两个部分.服务端也称为分布式配置中心,是一个独立的微服务 ...

  8. Spring Cloud(Dalston.SR5)--Feign 声明式REST客户端

    Spring Cloud 对 Feign 进行了封装,集成了 Ribbon 并结合 Eureka 可以实现客户端的负载均衡,Spring Cloud 实现的 Feign 客户端类名为 LoadBala ...

  9. Spring Cloud(Dalston.SR5)--Zuul 网关-微服务集群

    通过 url 映射的方式来实现 zuul 的转发有局限性,比如每增加一个服务就需要配置一条内容,另外后端的服务如果是动态来提供,就不能采用这种方案来配置了.实际上在实现微服务架构时,服务名与服务实例地 ...

随机推荐

  1. mysql字段添加修改删除

    MySQL添加字段和修改字段   MySQL添加字段的方法并不复杂,下面将为您详细介绍MYSQL添加字段和修改字段等操作的实现方法,希望对您学习MySQL添加字段方面会有所帮助. 1添加表字段 alt ...

  2. C++ API方式连接mysql数据库实现增删改查

    这里复制的 http://www.bitscn.com/pdb/mysql/201407/226252.html 一.环境配置 1,装好mysql,新建一个C++控制台工程(从最简单的弄起,这个会了, ...

  3. HslCommunication组件库使用说明

    一个由个人开发的组件库,携带了一些众多的功能,包含了数据网络通信,文件上传下载,日志组件,PLC访问类,还有一些其他的基础类库. nuget地址:https://www.nuget.org/packa ...

  4. Spring Boot 揭秘与实战(七) 实用技术篇 - 异步任务

    文章目录 1. Spring Boot 集成异步任务 2. 单发服务模式 3. 请求应答模式 4. 源代码 Spring 对异步任务具有很好的支持.这篇文章,我们透过 Spring Boot 来讲解下 ...

  5. 20165228 2017-2018-2 《Java程序设计》第4周学习总结

    20165228 2016-2017-2 <Java程序设计>第4周学习总结 教材学习内容总结 子类与继承 子类的定义:使用关键词extends class 子类名 extends 父类名 ...

  6. logminer使用测试库进行挖掘分析,10.2.0.5

    上一篇测试是在dg环境进行测试挖掘,但是如果客户存在一个测试库,那样使用日志挖掘的影响性更小.本篇进行测试分析. 测试环境介绍: oracle linux  5.6,vmware虚拟机,安装两套单实例 ...

  7. RNN-LSTM-GRU-BIRNN

    https://blog.csdn.net/wangyangzhizhou/article/details/76651116 共三篇 RNN的模型展开后多个时刻隐层互相连接,而所有循环神经网络都有一个 ...

  8. django-dailyfresh

    Hold on ,learn by myself! redis nosql - 不支持sql语法 - 存储数据都是KV形式 - Mongodb - Redis - Hbase hadoop - Cas ...

  9. javaweb防止表单重复提交

    参考孤傲苍狼 https://www.cnblogs.com/xdp-gacl/p/3859416.html 场景一:在网络延迟的情况下让用户有时间点击多次submit按钮导致表单重复提交 场景二:表 ...

  10. python猜数字(多种实现方法)

    设定一个理想数字比如:66,让用户输入数字,如果比66⼤,则显示猜测的结果⼤了:如果比66⼩,则显示猜测的结果小了;只有等于66,显示猜测结果 第一种方式(最简单的方式实现) n = 66 # 理想数 ...