Hazelcast и JCache в Spring Boot создают два экземпляра

Похоже, что автоматическая конфигурация загрузки Spring по умолчанию создаст два экземпляра hazelcast при использовании JCache и включенном кешировании (@EnableCaching)

Полный пример: https://github.com/dirkvanrensburg/hazelcast-springboot-jcache

TL; DR; Есть ли способ получить автоконфигурацию загрузки Spring для создания только одного экземпляра Hazelcast при включении кэширования через JCache?

Я создал демонстрационный проект загрузки Spring, добавив следующие зависимости:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>

    <dependency>
        <groupId>javax.cache</groupId>
        <artifactId>cache-api</artifactId>
    </dependency>

    <dependency>
        <groupId>com.hazelcast</groupId>
        <artifactId>hazelcast</artifactId>
    </dependency>

    <dependency>
        <groupId>com.hazelcast</groupId>
        <artifactId>hazelcast-spring</artifactId>
        <version>${hazelcast.version}</version>
    </dependency>

и добавив @EnableCaching в класс Application, Spring автоматически настроит Hazelcast, но запустит два экземпляра hazelcast, которые объединяются в кластер, как показано в журналах:

Members [2] {
    Member [192.168.1.157]:5701 - 3eabbe90-6815-49ff-8d93-9e4b12e67810
    Member [192.168.1.157]:5702 - e9c93366-2408-4726-965a-b21dcf897113 this
}

Кеширование работает, но мне не нужны два экземпляра Hazelcast.

Взломать

Мне удалось заставить его работать, предоставив собственный менеджер кеша:

@Bean
public CacheManager springHzProvider(HazelcastInstance instance) {
    return SpringHazelcastCachingProvider.getCacheManager(instance, null, new Properties());
}

и удаление зависимостей hazelcast и hazelcast-spring и добавление hazelcast-all:

    <dependency>
        <groupId>com.hazelcast</groupId>
        <artifactId>hazelcast-all</artifactId>
        <version>${hazelcast.version}</version>
    </dependency>

Но остается вопрос, есть ли лучший «правильный» способ достижения этого? В идеале без определения настраиваемого диспетчера кеша и добавления hazelcast-all


person dvanrensburg    schedule 10.02.2017    source источник
comment
См. github.com/hazelcast/hazelcast -код-образцы / дерево / мастер /. Вы можете добавить аннотацию @EnableAutoConfiguration, чтобы исключить класс HazelcastAutoConfigurtation Spring Boot и удалить свой метод springHzProvider. Это не идеальное решение, но немного чище.   -  person Neil Stevenson    schedule 10.02.2017
comment
Спасибо, это работает и на самом деле намного чище. Мне не нужно добавлять HazelcastClientProxy в путь к классам. Вы понимаете, что здесь происходит? Возможно, это ошибка в CacheAutoConfiguration? Если вы хотите добавить свой комментарий в качестве ответа, я приму его, поскольку он решает обе мои проблемы (пользовательский кеш-менеджер, добавление hazelcast-all)   -  person dvanrensburg    schedule 12.02.2017
comment
Сначала я подниму это как проблему с Spring Boot и добавлю ссылку   -  person Neil Stevenson    schedule 13.02.2017
comment
Сообщаем, что проблема устранена и будет доступна с Spring Boot 1.5.3.RELEASE.   -  person Stephane Nicoll    schedule 10.03.2017


Ответы (2)


@dvanrensburg Согласно комментариям, в качестве временного решения исключите класс HazelcastAutoConfiguration из автоконфигурации. Я зарегистрировал проблему с Spring Boot https://github.com/spring-projects/spring-boot/issues/8275, поскольку я думаю, что это основная причина, второй экземпляр не должен создаваться, если @EnableCaching запустил создание первого.

person Neil Stevenson    schedule 13.02.2017
comment
Спасибо, Нил. Я нашел другой способ заставить это работать и добавлю его как дополнительный ответ на вопрос ниже - person dvanrensburg; 17.02.2017

Я использовал решение Нила выше, но столкнулся с ситуацией, когда я не могу автоматически подключить экземпляр Hazelcast, созданный конфигурацией JCache. Похоже, что экземпляр создан вне Spring и зарегистрирован в контексте приложения.

Присваиваем экземпляру имя в конфиге

<instance-name>test</instance-name>

а затем добавление явного хука для переноса экземпляра в контекст

@Bean
public HazelcastInstance getInstance() {
    return Hazelcast.getHazelcastInstanceByName("test");
}

работает хорошо. HazelcastAutoconfiguration не запустится, поскольку у него есть условие для еще не существующего экземпляра.

Меня беспокоит только то, что это в значительной степени зависит от того факта, что для версии 1.5.1 Spring Boot конфигурация JCache создает этот экземпляр до того, как сработает HazelcastAutoconfiguration.

ОБНОВЛЕНИЕ. Я нашел лучшее решение с помощью @snicoll отличного сообщества Spring Boot.

Просто явно укажите Spring Boot, какую конфигурацию hazelcast использовать, и назовите экземпляр Hazelcast. Поместите следующее в application.properties spring.hazelcast.config=hazelcast.xml

Пример см. На странице https://github.com/dirkvanrensburg/hazelcast-springboot-jcache/tree/fixed

person dvanrensburg    schedule 16.02.2017