简体   繁体   English

在生产中绕过@Cacheable批注进行调试

[英]Bypassing the @Cacheable annotation in Production for debugging

I'm working on a new Spring based project and I was wondering, if i were to use the @Cacheable annotation found in Spring 3.1 or in the ehcache-spring-annotation project, how would you go about implementing a mechanism for bypassing the cache mechanism "on demand", eg for production debugging. 我正在研究一个基于Spring的新项目,我想知道,如果我要使用Spring 3.1或ehcache-spring-annotation项目中的@Cacheable批注,您将如何实现一种绕过缓存的机制“按需”机制,例如用于生产调试。

Let's say my application serves only REST requests, on occasion, i would like, for a single call (that i manually make) to get data directly from the "DB" (or what ever backend there is) and avoid and any caching on the way ( any caching). 假设我的应用程序有时仅服务REST请求,而我想通过一次调用(我手动进行)直接从“ DB”(或后端)中获取数据,并避免在服务器上进行任何缓存方式( 任何缓存)。 While the call is running, I don't really mind if it re-populates the cache with what it just got from the db... 当调用运行时,我真的不介意是否用从数据库中获取的内容重新填充缓存...

I would like to hear your thoughts on how you would go about implementing this. 我想听听您对如何实现这一目标的想法。

Thanks in advance for any guidance, 预先感谢您的指导,

Ken.

Arrived at a similar result as suggested by @Bozho If the request parameter refresh-cache=true is passed, the cache gets bypassed 到达与@Bozho建议的结果类似的结果如果传递了请求参数refresh-cache = true ,则绕过缓存

I extended DefaultRedisCacheWriter and used it as the CacheWriter 我扩展了DefaultRedisCacheWriter并将其用作CacheWriter

    RedisCacheManager cacheManager = RedisCacheManager
            .builder(new RefreshableRedisCacheWriter(redisConnectionFactory()))
            .cacheDefaults(cacheConfiguration)
            .build();

Overwrite the get() method in this writer 覆盖此编写器中的get()方法

@Override
public byte[] get(String name, byte[] key) {

    Assert.notNull(name, "Name must not be null!");
    Assert.notNull(key, "Key must not be null!");

    HttpServletRequest request = ApiRequestContext.getRequestContext();
    if (Boolean.valueOf(request.getParameter("refresh-cache"))) {
        logger.info("bypassing cache for key: {}", key);
        return null;
    }

    return execute(name, connection -> connection.get(key));
}

ApiRequestContext is a custom request object here stored in the thread local. ApiRequestContext是一个自定义请求对象,存储在本地线程中。 Note that when this method returns null, the value is fetched from the db and put back into the cache, effectively refreshing the cache. 请注意,当此方法返回null时,将从数据库中获取值并将其放回高速缓存中,从而有效地刷新高速缓存。

Perhaps you can extend the cache manager and provide a boolean expression in addition to the existing checks. 也许您可以扩展缓存管理器,并在现有检查之外提供布尔表达式。

That boolean you can set in a ThreadLocal in your controller, so that whenever the service is invoked, the boolean is in place. 您可以在控制器的ThreadLocal中设置该布尔值,以便每当调用服务时,布尔值就位。

You can create a method that flushes the cache and run it only with your debugger when you want a value from the DB. 您可以创建一种刷新缓存的方法,并且仅当需要从数据库获取值时才使用调试器运行它。

@Cacheable(modelId = "i18NTextCacheModel")
public List<I18NText> loadAll() {

    logger.debug("loadAll called");
    ...
}

@CacheFlush(modelId = "i18NTextFlushModel")
public Long save(I18NText entity) {

    logger.debug("save called");
    ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM