Spring boot 集成测试的spring boot Hazelcast配置

Spring boot 集成测试的spring boot Hazelcast配置,spring-boot,hazelcast,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() {

我们使用
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一起使用?

CacheManager is和iterface,在将CacheManager与hazelcast一起使用时,它将使用HazelcastCacheManagerImpl

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

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

如果我们检测到CacheManager与real hz失去连接,我们将开始尝试手动重新连接CacheManager,如果成功,则用新的链接替换到CacheManager的链接

这是一个如何在运行时重新初始化Springbean的问题

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


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

您是否也有相同的问题e最新的Hazelcast版本(3.10.5)?@Rafal Leszko:是的,3.10.5产生了同样的错误抱歉,再次@RafałLeszko:现在的错误是:
java.lang.IllegalStateException:CacheManager/hz/已经关闭。
我更新了这个问题。Dzmitry的回复有帮助吗?如果没有,让我知道,我会试着深入研究一下。部分帮助(见评论)。欢迎进一步的想法!:)我们不会在任何地方手动关闭HZ(只是上面的代码和服务层中的普通@Cache注释).
@DirtiesContext
确实有帮助,谢谢。但是,我们不喜欢为了修复hazelcast而使用它。欢迎进一步的想法!:)缓存初始化并工作时,您会有一些时间,在某些操作后连接会被删除,然后关闭。@DirtiesContext强制bean尽可能地重新生成-重新生成CacheManager连接to hz。若你们不手动关闭hz,并不意味着它不会因为任何其他原因关闭。我会看看为什么在测试过程中连接会像你们描述的那个样断开——但不知道会发生什么,所以这取决于你们。