spring 为集成测试启动 Hazelcast 配置
spring boot Hazelcast configuration for integration tests
我们使用 JCache
并使用以下缓存配置为 JCache
规范提供 backend/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 是 iterface,当 CacheManager 与 hazelcast 一起使用时,它使用 HazelcastCacheManagerImpl。
当与 hazelcast 的连接由于某种原因、异常、hazelcast 关闭等原因而断开或丢失时。HazelcastCacheManager 使用的内部 hazelcast 连接关闭并且整个 CacheManager 关闭时,尝试从此类缓存管理器获取特定的缓存,并且在此类缓存下执行 r/w 操作将导致 "java.lang.IllegalStateException: CacheManager /hz/ is already closed." 异常。
当 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 重新初始化并帮助获得可重复的测试结果。
我们使用 JCache
并使用以下缓存配置为 JCache
规范提供 backend/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 是 iterface,当 CacheManager 与 hazelcast 一起使用时,它使用 HazelcastCacheManagerImpl。
当与 hazelcast 的连接由于某种原因、异常、hazelcast 关闭等原因而断开或丢失时。HazelcastCacheManager 使用的内部 hazelcast 连接关闭并且整个 CacheManager 关闭时,尝试从此类缓存管理器获取特定的缓存,并且在此类缓存下执行 r/w 操作将导致 "java.lang.IllegalStateException: CacheManager /hz/ is already closed." 异常。
当 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 重新初始化并帮助获得可重复的测试结果。