Hystrix-请求缓存实战

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Anbang713/article/details/85721091

在《Hystrix-执行流程》中,我们说到在执行command的时候会先检查是否开启缓存,若开启缓存,且缓存中有数据时,就直接返回结果。今天,我们就通过实战看下这说的是什么意思。

一、创建command

重写getCacheKey方法,返回一个String类型的值作为缓存的key。

public class CommandUsingRequestCache extends HystrixCommand<Boolean> {

  private final int value;

  protected CommandUsingRequestCache(int value) {
    super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
    this.value = value;
  }

  @Override
  protected Boolean run() {
    return value == 0 || value % 2 == 0;
  }

  @Override
  protected String getCacheKey() {
    return String.valueOf(value);
  }

}

二、执行command

public class CommandUsingRequestCacheTest {

  public void testWithCacheHits() {
    HystrixRequestContext context = HystrixRequestContext.initializeContext();
    try {
      CommandUsingRequestCache commanda = new CommandUsingRequestCache(2);
      CommandUsingRequestCache commandb = new CommandUsingRequestCache(2);

      System.out.println("commandc execute result:" + commanda.execute());
      System.out.println("commandc is from cache:" + commanda.isResponseFromCache());
      System.out.println("-------------------------------------------");
      System.out.println("commandc execute result:" + commandb.execute());
      System.out.println("commandc is from cache:" + commandb.isResponseFromCache());
      System.out.println("-------------------------------------------");
    } finally {
      context.shutdown();
    }

    context = HystrixRequestContext.initializeContext();
    try {
      CommandUsingRequestCache commandc = new CommandUsingRequestCache(2);
      System.out.println("commandc execute result:" + commandc.execute());
      System.out.println("commandc is from cache:" + commandc.isResponseFromCache());
    } finally {
      context.shutdown();
    }
  }

  public static void main(String[] args) {
    CommandUsingRequestCacheTest test = new CommandUsingRequestCacheTest();
    test.testWithCacheHits();
  }
}

三、执行结果

四、总结 

从上诉执行结果我们可以看到,第一次执行isResponseFromCache方法返回false,即表示不是从缓存中获取的数据。第二次为true表示从缓存中直接返回结果。第三次返回false,理论上来说2已经在缓存中,但为什么这里返回false?原来,在Hystrix中有一个概念,叫做请求上下文,即HystrixRequestContext。commanda和commandb在同一个请求上下文中,所以当commandb再次访问时,就会直接取用缓存中的数据。但是commandb执行结束之后,我们关闭了上下文,在执行commandc之前重新创建了一个上下文,此时上下文中缓存数据是为空的,这就解释了为什么commandc.isResponseFromCache()返回的结果为false了。

一般来说,在一个web应用中,我们会在一个filter里面,对每一个请求都施加一个请求上下文,就是说tomcat容器内每一次请求就是一次请求上下文。然后在这次请求上下文中,我们会去执行N多代码,调用N多依赖服务,有的依赖服务可能还会调用好几次。在一次请求上下文中,如果有多个command,参数都是一样的,调用的接口也是一样的,其实结果可以认为也是一样的。那么这个时候,我们就可以让第一次command执行,返回的结果,被缓存在内存中,然后这个请求上下文中,后续的其他对这个依赖的调用全部从内存中取用缓存结果就可以了。不用在一次请求上下文中反复多次的执行一样的command,提升整个请求的性能。

猜你喜欢

转载自blog.csdn.net/Anbang713/article/details/85721091