Hystrix请求缓存示例

9
我将尝试解释 Hystrix 请求缓存 是如何工作的,但是我并没有理解他们在文档中提供的例子。

事实上,我有以下的 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的请求缓存是什么样子的(确切地说)?如何向缓存添加条目?何时/如何清空缓存?它是否可配置(过期时间、最大大小等)?


1
你可以阅读HystrixCommand的实现。一个起点可能是方法HystrixCommand.isResponseFromCache())(链接到grepcode.com)。 - MicSim
3个回答

9
根据您提供的文档实施请求缓存需要在HystrixCommand对象上实现getCacheKey()方法…。您尚未实现getCacheKey()方法,
@Override
protected String getCacheKey() {
    return String.valueOf(id); // <-- changed from `value` in example
}

然后您还需要一个HystrixRequestContext

HystrixRequestContext context = HystrixRequestContext.initializeContext();

根据文档,通常可以通过包装用户请求或其他生命周期钩子的ServletFilter来初始化和关闭此上下文。

然后我认为您不能像那样更改execute()的方法签名(doExecute()不是接口的一部分),而应将参数传递给命令构造函数,并请使用@Overrideexecute进行注释,以便在忘记时获得编译器错误 然后

HystrixRequestContext context = HystrixRequestContext.initializeContext();
GetFizzCommand commandA = new GetFizzCommand(2L);
GetFizzCommand commandB = new GetFizzCommand(2L);
Fizz a = commandA.execute(); // <-- should not be cached
Fizz b = commandB.execute(); // <-- should be cached.

1

您的控制器需要一个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();
    }
  }
}

0
如果您使用@HystrixCommand,您可以在方法参数上使用@com.netflix.hystrix.contrib.javanica.cache.annotation.CacheKey来生成请求缓存键。
@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的值


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接