【问题标题】:spring boot Hazelcast configuration for integration tests用于集成测试的 spring boot Hazelcast 配置
【发布时间】:2019-02-25 16:42:42
【问题描述】:

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

【问题讨论】:

  • 最新的 Hazelcast 版本 (3.10.5) 是否有同样的问题?
  • @Rafal Leszko:是的,3.10.5 产生同样的错误
  • 对不起,再次@RafałLeszko:现在的错误是:java.lang.IllegalStateException: CacheManager /hz/ is already closed.我更新了问题。
  • Dzmitry 的回复有帮助吗?如果没有,请告诉我,我会尝试深入研究。
  • 部分确实有帮助(见评论)。欢迎进一步的想法! :)

标签: spring-boot hazelcast


【解决方案1】:

CacheManager 是和 iterface,当使用带有 hazelcast 的 CacheManager 时,它使用 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重新初始化并帮助获得可重复的测试结果。

【讨论】:

  • 我们不会在任何地方手动关闭HZ(只是上面的代码和服务层中的普通@Cache注解)。 @DirtiesContext 确实有帮助,谢谢。但是,我们不喜欢将它用于修复 hazelcast。欢迎进一步的想法! :)
  • 您有一段时间缓存初始化并工作,在某些操作后连接断开并关闭。 @DirtiesContext 强制 bean 重新初始化 - 重新初始化与 hz 的 CacheManger 连接。如果您不手动关闭 hz 并不意味着它没有因任何其他原因关闭。正如您所描述的,我会看看为什么在测试期间连接会断开 - 但不知道那里会发生什么,所以这取决于您。
猜你喜欢
  • 2017-02-03
  • 2021-01-24
  • 2016-12-30
  • 2022-01-19
  • 2019-07-11
  • 2020-02-25
  • 1970-01-01
  • 2015-06-14
  • 1970-01-01
相关资源
最近更新 更多