Кэширование запросов Hystrix на примере

Я пытаюсь понять, как работает кэширование запросов 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 (точно)? Как записи добавляются в кэш? Как/когда очищается кеш? Можно ли его настроить (сроки действия, максимальные размеры и т. д.)?


person IAmYourFaja    schedule 25.11.2014    source источник
comment
Вы можете прочитать о реализации HystrixCommand. Отправной точкой будет метод HystrixCommand.isResponseFromCache()) (ссылки на grepcode.com).   -  person MicSim    schedule 28.11.2014


Ответы (3)


Согласно документации, на которую вы ссылаетесь здесь,

Кэширование запросов включается путем реализации метода getCacheKey() для объекта HystrixCommand...

Вы не реализовали getCacheKey(),

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

Тогда вам также понадобится HystrixRequestContext.

HystrixRequestContext context = HystrixRequestContext.initializeContext();

Что (опять же, согласно документации)

Обычно этот контекст инициализируется и выключается с помощью ServletFilter, обертывающего пользовательский запрос или какой-либо другой хук жизненного цикла.

Тогда я считаю, что вы не можете изменить сигнатуру метода execute() таким образом (doExecute() не является частью интерфейса), вместо этого вы передаете параметр конструктору команды и, пожалуйста, аннотируете execute с помощью @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.
person Elliott Frisch    schedule 30.11.2014

Вам нужен 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();
    }
  }
}
person Zgpeace    schedule 04.03.2020

Если вы используете @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

person chen gao    schedule 09.04.2021