zoukankan      html  css  js  c++  java
  • Spring Cloud(Dalston.SR5)--Hystrix 断路器-缓存

    在 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 缓存。

         

         

         

  • 相关阅读:
    Building a flexiable renderer
    Indirect Illumination in mental ray
    我的心情
    Cellular Automata
    Subsurface Scattering in mental ray
    Shader Types in mental ray
    BSP Traversal
    我的渲染器终于达到了MR的速度
    How to handle displacement and motion blur
    说明
  • 原文地址:https://www.cnblogs.com/li3807/p/8916816.html
Copyright © 2011-2022 走看看