java 在spring Boot 中重新加载/刷新缓存

x33g5p2x  于 2023-04-28  发布在  Java
关注(0)|答案(6)|浏览(305)

我使用Sping Boot ,缓存我使用Ehcache。到现在为止都很好。但是现在我必须重新加载/刷新,那么我如何才能做到这一点,使我的应用程序不会有任何停机时间。
我在Spring Ehcache中尝试了很多方法,但都不起作用,或者必须编写调度程序并重新加载数据。

@Override
@Cacheable(value="partTypeCache", key="#partKey")
public List<PartType> loadPartType(String partKey) throws CustomException {
        return productIdentityDao.loadPartType();
}
z9zf31ra

z9zf31ra1#

显然,关于你的问题的所有评论都是正确的。你应该使用CacheEvict。我在这里找到了解决方案:https://www.baeldung.com/spring-boot-evict-cache看起来像这样:
你所要做的就是创建一个名为e的类。g. CacheService和create方法,该方法将驱逐所有缓存的对象。然后,您注解该方法@Scheduled,并输入您的间隔率。

@Service
public class CacheService {

    @Autowired
    CacheManager cacheManager;

    public void evictAllCaches() {
        cacheManager.getCacheNames().stream()
          .forEach(cacheName -> cacheManager.getCache(cacheName).clear());
    }

    @Scheduled(fixedRate = 6000)
    public void evictAllcachesAtIntervals() {
        evictAllCaches();
    }

}
isr3a4wc

isr3a4wc2#

许多人建议使用@CacheEvict的选项是正确的。此外,为了确保缓存(near)始终加载最新数据,即使数据库中的数据更新超出了您正在运行的应用的范围,您也需要定期重新加载整个数据集,时间间隔与应用的SLA相匹配。在建议的解决方案above中,添加逻辑以重新加载所有数据,如下所示:

@Service
public class CacheService {

    @Autowired
    CacheManager cacheManager;

    public void refreshAllCaches() {
        cacheManager.getCacheNames().stream()
          .forEach(cacheName -> cacheManager.getCache(cacheName).clear());
        // reload whole dataset here, dummy example here:
        dataRepository.findAll().forEach(a -> cacheManager.getCache("cache-name")).put(a.getKey(), a));
    }

    @Scheduled(fixedRate = 6000)
    public void refreshAllcachesAtIntervals() {
        refreshAllCaches();
    }

}
biswetbf

biswetbf3#

尝试类似这样的东西,如评论中所提到的:

@Caching(evict={@CacheEvict(value="partTypeCache", key="#partKey")})
    public boolean deletePartType(String partKey) { 
      //when this method is invoked the cache is evicted for the requested key
    }
t98cgbkg

t98cgbkg4#

除了上面的答案,你可以在你的调度程序中使用cron,这会提供更多的灵活性。你可以有一个调度程序运行每天,每周,每年,每天12点等,而不需要写很多代码。

public class CacheService {

@Autowired
CacheManager cacheManager;

public void evictAllCaches() {
    cacheManager.getCacheNames().stream()
      .forEach(cacheName -> cacheManager.getCache(cacheName).clear());
}

@Scheduled(cron = "@weekly")
public void evictAllcachesAtIntervals() {
    evictAllCaches();
}

}

ymzxtsji

ymzxtsji5#

您是否知道您具体希望续订哪些partKey?如果你不这样做,你必须从该高速缓存本身找到密钥。您可以使用@CachePut来更新缓存值,而无需停机。我的建议的性能不会很好,但它应该做的正是你正在寻找的。
具体针对EhCache:

public void renewCache() {
    net.sf.ehcache.EhCache cache = (net.sf.ehcache.EhCache) org.springframework.cache.CacheManager.getCache("partTypeCache").getNativeCache();
    for (Object key : cache.getKeys()) {
          updatePartTypeCache((String) key)
    }
}

@CachePut(value="partTypeCache", key="#partKey")
public List<PartType> updatePartTypeCache(String partKey) throws CustomException {
        return productIdentityDao.loadPartType();
}

需要说明的是,最糟糕的部分是从现有缓存中获取密钥。如果您有一个想要保存在缓存中的“热”部分的简短列表,则可以调用updatePartTypeCache来处理这些部分。

rhfm7lfc

rhfm7lfc6#

要求是以X间隔刷新1个缓存,以Y间隔刷新另一个缓存。如果我们只在一个类中编写下面的代码,该高速缓存不会重新加载。

public class XXXSchedulers {

    @Autowired
    private XXXUtil util;

    @Scheduled(fixedDelay = 10 * 60 * 1000) // Running after 10 minutes
    public void clearSpecificABCCache() {
        util.clearSpecificABCCache();
        util.getABC();//Again gets value in the cache
    }

    @Scheduled(cron = "0 0 2 * * ?") //Running Everyday at 2 AM public void 
    public void clearSpecificXYZCache() {
        util.clearSpecificABCCache();
        util.getXYZ();
    }
}

@Component
public class XXXUtil {
    @Autowired
    private CacheManager cacheManager;

    @Autowired
    private XXXService service;

    @Cacheable("abc")
    public ABC getABC() {
        ABC abc = service.getABC();
    }

    public void clearSpecificABCCache() {
        cacheManager.getCache("abc").clear();
    }

    @Cacheable("xyz")
    public XYZ getXYZCache() {
        XYZ xyz = service.getXYZCache();
    }
    
    public void clearSpecificXYZCache() {
        cacheManager.getCache("xyz").clear();
    }
  }

相关问题