Hystrix请求缓存示例

时间:2014-11-25 00:59:12

标签: java caching fault-tolerance hystrix

我想知道Hystrix request caching的工作原理,但我没有关注他们在文档中提供的wiki或端到端示例。

基本上我有以下HystrixCommand子类:

public class GetFizzCommand extends HystrixCommand<Fizz> {
    private Long id;
    private Map<Long,Fizz> fizzCache = new HashMap<Long,Fizz>();

    void doExecute(Long id) {
        this.id = id;
        execute();
    }

    @Override
    public Fizz run() {
        return getFizzSomehow();
    }

    @Override
    public Fizz getFallback() {
        // Consult a cache somehow.
        // Perhaps something like a Map<Long,Fizz> where the 'id' is the key (?)
        // If the 'id' exists in the cache, return it. Otherwise, give up and return
        // NULL.
        fizzCache.get(id);
    }
}

所以我觉得我在这里反对。我相信 Hystrix提供内置缓存,如'cacheKey'所示,但我找不到任何有效的例子。我不想在这里重新发明轮子,如果已经开箱即可提供缓存到我的命令中。

所以我问:Hystrix(确切地说)请求缓存是什么样的?如何将条目添加到缓存中?如何/何时刷新缓存?它是可配置的(expiries,max sizes等)吗?

3 个答案:

答案 0 :(得分:6)

根据您链接到here的文档,

  

通过在getCacheKey()对象上实施HystrixCommand方法启用请求缓存...

您尚未实施getCacheKey()

@Override
protected String getCacheKey() {
    return String.valueOf(id); // <-- changed from `value` in example
}

然后你还需要一个HystrixRequestContext

HystrixRequestContext context = HystrixRequestContext.initializeContext();

这是(再次,根据文件)

  

通常,此上下文将通过包装用户请求或其他生命周期挂钩的ServletFilter进行初始化和关闭。

然后我相信你不能改变execute()的方法签名(doExecute()不是接口的一部分)而是将参数传递给你的命令构造函数并请注释{{1}使用execute,如果忘记然后

,就会出现编译错误
@Override

答案 1 :(得分:0)

您的控制器中需要一个HystrixRequestContext

//init
HystrixRequestContext context = HystrixRequestContext.initializeContext();
// get cache logic ...

//close
context.close();

更好的方法是添加一个过滤器类。

import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@Component
@WebFilter(urlPatterns = "/*", asyncSupported = true)
public class HystrixRequestContextFilter implements Filter {
  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HystrixRequestContext context = HystrixRequestContext.initializeContext();
    try {
      filterChain.doFilter(servletRequest, servletResponse);
    } finally {
      context.close();
    }
  }
}

答案 2 :(得分:0)

如果使用@HystrixCommand,可以在method参数上使用@com.netflix.hystrix.contrib.javanica.cache.annotation.CacheKey来生成请求缓存key,

@Component
public class SpringBootMockRemoteService {

    @HystrixCommand(fallbackMethod = "fallback")
    public String getRemoteValue(@CacheKey String username) throws InterruptedException {
        Thread.sleep(3_000);
        return "SUCCESS";
    }

    String fallback() {
        return "FALLBACK";
    }
}

请求缓存键将是参数username的值