Sepehr GH
Sepehr GH

Reputation: 1397

How autoconfigure hazel cast with spring boot eureka discovery

I'm new to hazelcast and I want to use Hazelcast as distributed map between some of my application instances. I cant find good documentation about it. What I want is multi hazelcast server instances to discover each other and share a map.

Here is what I have done for beggining.

My dependencies in POM.xml

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

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

    <dependency>
        <groupId>com.hazelcast</groupId>
        <artifactId>hazelcast-eureka-one</artifactId>
        <version>1.0.2</version>
    </dependency>

Configuration:

@Bean
    public Config configuration(@Value("eureka.client.service-url.defaultZone") String eurekaAddress) {
        Config config = new Config();
        MapConfig mapConfig = new MapConfig("priorities")
                .setTimeToLiveSeconds(10 * 60)
                .setEvictionPolicy(EvictionPolicy.LRU)
                .setMaxSizeConfig(new MaxSizeConfig(10, MaxSizeConfig.MaxSizePolicy.FREE_HEAP_SIZE));
        config.addMapConfig(mapConfig);
        NetworkConfig networkConfig = new NetworkConfig();
        JoinConfig joinConfig = new JoinConfig();
        AwsConfig awsConfig = new AwsConfig();
        awsConfig.setEnabled(false);
        joinConfig.setAwsConfig(awsConfig);
        TcpIpConfig tcpIpConfig = new TcpIpConfig();
        tcpIpConfig.setEnabled(true);
        joinConfig.setTcpIpConfig(tcpIpConfig);
        MulticastConfig multicastConfig = new MulticastConfig();
        multicastConfig.setEnabled(false);
        joinConfig.setMulticastConfig(multicastConfig);
        DiscoveryConfig eurekaDiscoveryConfig = new DiscoveryConfig();
        Map<String, Comparable> map = new HashMap<>();
        map.put("use-classpath-eureka-client-props", false);
        map.put("shouldUseDns", false);
//        map.put("name", "hazelcast-cache-cluster");
        map.put("serviceUrl.default", eurekaAddress);
        DiscoveryStrategyConfig eurekaDiscoveryStrategyConfig = new DiscoveryStrategyConfig(
            new EurekaOneDiscoveryStrategyFactory(),
            map
        );
        eurekaDiscoveryConfig.addDiscoveryStrategyConfig(eurekaDiscoveryStrategyConfig);
        joinConfig.setDiscoveryConfig(eurekaDiscoveryConfig);
        networkConfig.setJoin(joinConfig);
        config.setNetworkConfig(networkConfig);
        config.setProperty("hazelcast.discovery.enabled", "true");
        return config;
    }

and application properties:

eureka.client.service-url.defaultZone=${EUREKA_URI:http://localhost:8761/eureka}
eureka.instance.prefer-ip-address=true

Here is error I get:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hazelcastInstance' defined in class path resource [org/springframework/boot/autoconfigure/hazelcast/HazelcastServerConfiguration$HazelcastServerConfigConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.hazelcast.core.HazelcastInstance]: Factory method 'hazelcastInstance' threw exception; nested exception is java.lang.RuntimeException: Failed to configure discovery strategies
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:625) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:605) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1288) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:846) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:863) ~[spring-context-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546) ~[spring-context-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) [spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) [spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) [spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) [spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at com.dropin.azeron.AzeronApplication.main(AzeronApplication.java:11) [classes/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.hazelcast.core.HazelcastInstance]: Factory method 'hazelcastInstance' threw exception; nested exception is java.lang.RuntimeException: Failed to configure discovery strategies
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:620) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    ... 19 common frames omitted
Caused by: java.lang.RuntimeException: Failed to configure discovery strategies
    at com.hazelcast.spi.discovery.impl.DefaultDiscoveryService.loadDiscoveryStrategies(DefaultDiscoveryService.java:149) ~[hazelcast-3.11.jar:3.11]
    at com.hazelcast.spi.discovery.impl.DefaultDiscoveryService.<init>(DefaultDiscoveryService.java:57) ~[hazelcast-3.11.jar:3.11]
    at com.hazelcast.spi.discovery.impl.DefaultDiscoveryServiceProvider.newDiscoveryService(DefaultDiscoveryServiceProvider.java:29) ~[hazelcast-3.11.jar:3.11]
    at com.hazelcast.instance.Node.createDiscoveryService(Node.java:285) ~[hazelcast-3.11.jar:3.11]
    at com.hazelcast.instance.Node.<init>(Node.java:233) ~[hazelcast-3.11.jar:3.11]
    at com.hazelcast.instance.HazelcastInstanceImpl.createNode(HazelcastInstanceImpl.java:156) ~[hazelcast-3.11.jar:3.11]
    at com.hazelcast.instance.HazelcastInstanceImpl.<init>(HazelcastInstanceImpl.java:126) ~[hazelcast-3.11.jar:3.11]
    at com.hazelcast.instance.HazelcastInstanceFactory.constructHazelcastInstance(HazelcastInstanceFactory.java:202) ~[hazelcast-3.11.jar:3.11]
    at com.hazelcast.instance.HazelcastInstanceFactory.newHazelcastInstance(HazelcastInstanceFactory.java:181) ~[hazelcast-3.11.jar:3.11]
    at com.hazelcast.instance.HazelcastInstanceFactory.newHazelcastInstance(HazelcastInstanceFactory.java:131) ~[hazelcast-3.11.jar:3.11]
    at com.hazelcast.core.Hazelcast.newHazelcastInstance(Hazelcast.java:57) ~[hazelcast-3.11.jar:3.11]
    at org.springframework.boot.autoconfigure.hazelcast.HazelcastInstanceFactory.getHazelcastInstance(HazelcastInstanceFactory.java:82) ~[spring-boot-autoconfigure-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.boot.autoconfigure.hazelcast.HazelcastServerConfiguration$HazelcastServerConfigConfiguration.hazelcastInstance(HazelcastServerConfiguration.java:67) ~[spring-boot-autoconfigure-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.boot.autoconfigure.hazelcast.HazelcastServerConfiguration$HazelcastServerConfigConfiguration$$EnhancerBySpringCGLIB$$baa97a38.CGLIB$hazelcastInstance$0(<generated>) ~[spring-boot-autoconfigure-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.boot.autoconfigure.hazelcast.HazelcastServerConfiguration$HazelcastServerConfigConfiguration$$EnhancerBySpringCGLIB$$baa97a38$$FastClassBySpringCGLIB$$57fb2fb0.invoke(<generated>) ~[spring-boot-autoconfigure-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363) ~[spring-context-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.boot.autoconfigure.hazelcast.HazelcastServerConfiguration$HazelcastServerConfigConfiguration$$EnhancerBySpringCGLIB$$baa97a38.hazelcastInstance(<generated>) ~[spring-boot-autoconfigure-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_191]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_191]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_191]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_191]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    ... 20 common frames omitted
Caused by: java.lang.IllegalStateException: ConfigurationManager is already initialized with configuration com.netflix.config.ConcurrentCompositeConfiguration@2342f1ff
    at com.netflix.config.DynamicPropertyFactory.initWithConfigurationSource(DynamicPropertyFactory.java:147) ~[archaius-core-0.7.5.jar:0.7.5]
    at com.hazelcast.eureka.one.PropertyBasedEurekaClientConfig.<init>(PropertyBasedEurekaClientConfig.java:57) ~[hazelcast-eureka-one-1.0.2.jar:na]
    at com.hazelcast.eureka.one.EurekaOneDiscoveryStrategy.<init>(EurekaOneDiscoveryStrategy.java:160) ~[hazelcast-eureka-one-1.0.2.jar:na]
    at com.hazelcast.eureka.one.EurekaOneDiscoveryStrategy.<init>(EurekaOneDiscoveryStrategy.java:60) ~[hazelcast-eureka-one-1.0.2.jar:na]
    at com.hazelcast.eureka.one.EurekaOneDiscoveryStrategy$EurekaOneDiscoveryStrategyBuilder.build(EurekaOneDiscoveryStrategy.java:116) ~[hazelcast-eureka-one-1.0.2.jar:na]
    at com.hazelcast.eureka.one.EurekaOneDiscoveryStrategyFactory.newDiscoveryStrategy(EurekaOneDiscoveryStrategyFactory.java:56) ~[hazelcast-eureka-one-1.0.2.jar:na]
    at com.hazelcast.spi.discovery.impl.DefaultDiscoveryService.buildDiscoveryStrategy(DefaultDiscoveryService.java:183) ~[hazelcast-3.11.jar:3.11]
    at com.hazelcast.spi.discovery.impl.DefaultDiscoveryService.loadDiscoveryStrategies(DefaultDiscoveryService.java:141) ~[hazelcast-3.11.jar:3.11]
    ... 42 common frames omitted

How can I use eureka as discovery for both my app and hazelcast? I think there should be a way that hazelcast discovers itself when I use @EnableEurekaClient.

Upvotes: 1

Views: 3202

Answers (2)

pkoli
pkoli

Reputation: 676

Updating the version of hazelcast-eureka-one to 1.1 solved the issue for me. Also I'm using the same EurekaClient for both the springboot application and Hazelcast.

I've set use-metadata-for-host-and-port to true in the Hazelcast config, that solves the issue.

Config config = new Config();
    config.getNetworkConfig().setPort(hazelcastPort);
    config.getProperties().setProperty("hazelcast.discovery.enabled", "true");
    JoinConfig joinConfig = config.getNetworkConfig().getJoin();
    joinConfig.getMulticastConfig().setEnabled(false);
    EurekaOneDiscoveryStrategyFactory.setEurekaClient(eurekaClient);
    EurekaOneDiscoveryStrategyFactory discoveryStrategyFactory = new EurekaOneDiscoveryStrategyFactory();
    Map<String, Comparable> properties = new HashMap<String, Comparable>();
    properties.put("self-registration", "true");
    properties.put("namespace", "hazelcast");
    properties.put("use-metadata-for-host-and-port", "true");
    DiscoveryStrategyConfig discoveryStrategyConfig = new DiscoveryStrategyConfig(discoveryStrategyFactory, properties);
    joinConfig.getDiscoveryConfig().addDiscoveryStrategyConfig(discoveryStrategyConfig);

    return config;

You can refer the entire code here https://github.com/pkoli/session-clustering

Upvotes: 0

Rafał Leszko
Rafał Leszko

Reputation: 5541

You can find a related issue here: Hazelcast cluster not available on Eureka

In general, if you use Eureka just for the Hazelcast discovery, then the hazelcast-eureka plugin should work out of the box. If you need to use Eureka for both your application and Hazelcast, you have to use the use-metadata-for-host-and-port property or a separate EurekaClient.

I have prepare Hazelcast Eureka plugin Code Sample.

EDIT: I just found metadata-for-host-and-port is not released yet, it will be released in hazecast-eureka 1.0.3. Saying that, you can build it yourself and check how to use it here.

Upvotes: 2

Related Questions