Попадания в кеш журнала Spring JCache

У меня есть метод, в котором я добавил кеш, добавив аннотацию @CacheResult (я фактически создал прокси, потому что не могу изменить исходную реализацию SomethingService):

@Service
public class SomethingServiceProxyImpl implements SomethingService {

    @Autowired
    @Qualifier("somethingService")
    SomethingService somethingService;

    @Override
    @CacheResult(cacheName = "somethingCache", exceptionCacheName = "somethingExceptionCache", cachedExceptions = { SomeException.class })
    public SomePojo someMethod(String someArg) {
        return somethingService.someMethod(someArg);
    }
}

Что мне нужно сейчас, так это иметь возможность регистрировать попадания в кеш, то есть случаи, когда возвращаемый результат был результатом из кеша. Я просмотрел Spring Cache, JCache и EHCache (используемую мной реализацию), и я нашел только способ прослушивания (со слушателями) следующих событий: CREATED, UPDATED, REMOVED, EVICTED, EXPIRED, но ни один из них не событие, когда кеш вернул результат (не нуль).

Я действительно не хочу менять реализацию, чтобы программно использовать кеш вместо использования аннотаций (на самом деле мне нужно изменить много сервисов, а не только один), есть ли в любом случае хороший способ регистрировать эти события?


person Nyamiou The Galeanthrope    schedule 26.02.2019    source источник
comment
JCache не создает событие для каждого попадания в кэш. Я думаю, что вы можете отслеживать попадания в кеш, только если у вас есть код, который вызывает cache.get.   -  person Vassilis Bekiaris    schedule 28.02.2019
comment
Это то, что я узнал, к сожалению, код, который выполняет cache.get, находится внутри Spring Framework, это CacheResultInterceptor и это частный класс пакета.   -  person Nyamiou The Galeanthrope    schedule 28.02.2019
comment
Есть ли у вас бизнес-логика в отношении попадания в кеш? Если нет, вы можете включить статистику, чтобы получить накопленные показатели.   -  person Ben Manes    schedule 28.02.2019
comment
Клиент хочет, чтобы в логах приложения были кэшированные попадания, поэтому с помощью нашего ELK он может получить эти метрики на нашей Kibana. Наконец, я сказал клиенту вычесть запрос из создания кеша, чтобы получить попадания в кеш.   -  person Nyamiou The Galeanthrope    schedule 01.03.2019


Ответы (1)


Мысли на эту тему. Вероятно, первые два являются наиболее актуальными:

Нельзя: код, который выполняется в Spring, и соответствующий кеш при попадании в кеш являются наиболее важными для производительности. Вот почему не так умно позволять вызывать дополнительный код в этом случае или даже иметь возможность для этого. Проводка в журнале сильно повлияет на вашу производительность. Обычно приложение уже регистрирует все, что приводит к запросу кеша (например, входящие веб-запросы). Чтобы понять, правильно ли работает кеш, достаточно счетчика обращений. Это доступно через статистику JCache JMX.

Адаптер ведения журнала. Используя Spring, вы можете написать адаптер кэша, который ведет журнал по мере необходимости и подключает его через конфигурацию. Грубая идея: посмотрите на интерфейсы CacheManager и Cache. Оберните метод CacheManager create cache и верните обернутый кеш с ведением журнала.

Взлом с помощью ExpiryPolicy: если указан пользовательский ExpiryPolicy, реализация JCache вызывает метод getExpiryForAccess при каждом доступе к кешу. Однако вы не получаете никакой информации о запрашиваемом ключе. Я также рекомендую держаться подальше от собственных реализаций ExpiryPolicy из соображений производительности. Так что это только для полноты.

Ведение кеша в журнал / регистрация каждого доступа: если вы укажете несколько кешей, Spring вызывает их один за другим. Вы можете подключить фиктивный кеш в качестве первого кеша, который просто регистрирует доступ.

person cruftex    schedule 19.03.2019
comment
Спасибо, это действительно полезно. - person Nyamiou The Galeanthrope; 19.03.2019