用于集成测试的Spring Boot Hazelcast配置

时间:2018-09-21 09:41:59

标签: spring-boot hazelcast

我们使用JCache,并使用以下缓存配置为JCache规范提供后端/ CacheManager。 Hazelcast是在spring之前自动配置的,因此我们不需要显式提供CacheManager,而只需提供我们的hazlecast配置。

@Configuration
public class CacheConfig {
    public static final int TTL_INFINITE = 0;

    @Bean
    public Config hazelCastConfig() {
        // do not allow hazelcast to send data to hazelcast, see
        // http://docs.hazelcast.org/docs/latest-development/manual/html/Preface/Phone_Home.html
        GroupProperty.PHONE_HOME_ENABLED.setSystemProperty("false");
        return new Config()
                .setInstanceName("hazelcast-instance")
                // create a cache
                .addCacheConfig(new CacheSimpleConfig()
                        .setName(RateLimiterServiceImpl.CACHE_NAME))
                // store it distributed
                .addMapConfig(new MapConfig()
                        .setName(RateLimiterServiceImpl.CACHE_NAME)
                        .setTimeToLiveSeconds(RateLimiterServiceImpl.CACHE_SECONDS_TO_LIVE)
                        .setEvictionPolicy(EvictionPolicy.LFU))
                // create a cache
                .addCacheConfig(new CacheSimpleConfig()
                        .setName(I18nServiceImpl.CACHE_NAME))
                // store it distributed
                .addMapConfig(new MapConfig()
                        .setName(I18nServiceImpl.CACHE_NAME)
                        .setTimeToLiveSeconds(I18nServiceImpl.CACHE_SECONDS_TO_LIVE)
                        .setEvictionPolicy(EvictionPolicy.LRU));
    }

}

在生产中以及在本地运行测试时,一切都很好。但是,使用gitlab CI时,在集成测试中会出现以下错误:

java.lang.IllegalStateException: null
        at com.hazelcast.cache.impl.AbstractHazelcastCacheManager.checkIfManagerNotClosed(AbstractHazelcastCacheManager.java:374) ~[hazelcast-3.9.2.jar:3.9.2]

以及hazelcast 3.10.5

java.lang.IllegalStateException: CacheManager /hz/ is already closed.
    at com.hazelcast.cache.impl.AbstractHazelcastCacheManager.ensureOpen(AbstractHazelcastCacheManager.java:366) ~[hazelcast-3.10.5.jar:3.10.5]
    at com.hazelcast.cache.impl.AbstractHazelcastCacheManager.getCache(AbstractHazelcastCacheManager.java:219) ~[hazelcast-3.10.5.jar:3.10.5]
    at com.hazelcast.cache.impl.AbstractHazelcastCacheManager.getCache(AbstractHazelcastCacheManager.java:67) ~[hazelcast-3.10.5.jar:3.10.5]
    at org.springframework.cache.jcache.JCacheCacheManager.getMissingCache(JCacheCacheManager.java:114) ~[spring-context-support-4.3.8.RELEASE.jar:4.3.8.RELEASE]
    at org.springframework.cache.support.AbstractCacheManager.getCache(AbstractCacheManager.java:97) ~[spring-context-4.3.8.RELEASE.jar:4.3.8.RELEASE]

这是测试失败:

mockMvc.perform(put("/translations/{locale}", locale)
                    .contentType(MediaType.APPLICATION_JSON_UTF8)
                    .content(dto)
                    .andExpect(status().isNoContent());
// gives a 500 with the above error message

我们应该如何配置集成测试以使用hazelcast?

1 个答案:

答案 0 :(得分:0)

CacheManager是iterface,当将CacheManager与hazelcast一起使用时,它使用HazelcastCacheManagerImpl。

当由于某种原因导致与hazelcast的连接被断开或丢失时,异常,hazelcast被关闭等。HazelcastCacheManager使用的内部hazelcast连接已关闭,并且整个CacheManager都已关闭,请尝试从此类缓存管理器获取特定的Cache并执行在此类高速缓存下执行/ w操作将导致“ java.lang.IllegalStateException:CacheManager / hz /已关闭”。

当hazelcast重新恢复(重新连接)时,您需要手动将CacheManager重新连接到hazelcast。我使用了3.5.7版本的hazelcast,为了解决此问题,我们创建了CacheManager作为代理bean。

如果我们检测到CacheManager失去了与真实hz的连接,我们将尝试手动重新连接CacheManager,并在成功的情况下,用新的链接替换到CacheManager的链接。

这是一个问题,如何在运行时重新初始化spring bean。

我认为在您的测试中您有类似的情况,在与hz的测试连接丢失期间,缓存已关闭。即使重新启动hazelcast,但不重新初始化CacheManager bean,它也可能指向旧的已关闭的hz连接,并且不会自动重新连接。

如果使用@SpringBootTest机制,则使用注释@DirtiesContext可能会有所帮助,因此每个测试都将重新初始化整个spring上下文,因此,如果在先前的测试中您破坏了hazelcast连接,请重新启动hz,否则在下一个测试中DirtiesContext将强制CacheManger重新初始化并帮助获得可重复的测试结果。