9

我试图弄清楚Hystrix 请求缓存是如何工作的,但没有遵循他们在文档中提供的 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 的请求缓存是什么样的(确切地说)?如何将条目添加到缓存中?如何/何时刷新缓存?它是否可配置(到期、最大大小等)?

4

3 回答 3

9

根据您链接到此处的文档,

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

你还没有实现getCacheKey()

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

那你还需要一个HystrixRequestContext

HystrixRequestContext context = HystrixRequestContext.initializeContext();

这是(再次,根据文档)

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

然后我相信你不能改变这样的方法签名execute()doExecute()不是接口的一部分),而是你将参数传递给你的命令构造函数并请execute用 an注释,@Override这样如果你忘记然后你会得到一个编译器错误

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.
于 2014-11-30T03:24:45.670 回答
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();
    }
  }
}
于 2020-03-04T01:42:09.200 回答
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

于 2021-04-09T12:56:47.610 回答