在 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. python 爬虫数据准换时间格式

    timeStamp = 1381419600 dateArray = datetime.datetime.utcfromtimestamp(timeStamp) otherStyleTime = da ...

  2. Windows10下pip的配置文件设置

    pip.ini的内容: [global] index-url = http://mirrors.aliyun.com/pypi/simple trusted-host = mirrors.aliyun ...

  3. 16 多校8 Rikka with Parenthesis II

    As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some mat ...

  4. ssm 配置多个数据源

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  5. SQL语句报错,无法绑定由多个部分组成的标识符解决

    无法绑定由多个部分组成的标识符, 表示在查询的时候使用了别名,并且查询的多个表中存在相同的字段,如果在使用该字段时不明确该字段的来源就会报这个错误. 举例: 我们有两张表,B1,B2,他们有一个共同的 ...

  6. element.dataset API

    不久之前我向大家展示了非常有用的classList API,它是一种HTML5里提供的原生的对页面元素的CSS类进行增.删改的接口,完全可以替代jQuery里的那些CSS类操作方法.而另外一个非常有用 ...

  7. Windows在当前目录打开cmd

    /********************************************************************** * Windows在当前目录打开cmd * 说明: * ...

  8. Gym101482 NWERC 2014(队内训练第4场)

    -----------------------前面的两场感觉质量不高,就没写题解----------------------------- A .Around the Track pro:给定内多边形 ...

  9. 打开视图 :1449 - the user specified as a definer ('root'@'%')does not exist

    从一个数据库数据迁移到本地localhost   程序在调用到数据库的视图时报错,直接在数据库中打开视图时也报错,类似:   mysql 1449 : The user specified as a ...

  10. MyBatis 遍历数组放入in中

    必须要遍历出数组的值放入in中 如果直接将"'2','3','4','5','6','7','8'" 字符串放入in中,只会查出 inv_operate_type的值为2的数据,因 ...