Hazelcast Sample
Clustered Spring Boot Admin Server deployment using Hazelcast for distributed event storage. This sample demonstrates high-availability setup where multiple Admin Server instances share state via Hazelcast.
Overview
Location: spring-boot-admin-samples/spring-boot-admin-sample-hazelcast/
Features:
- Distributed event store with Hazelcast
- Multi-instance clustering
- Shared notification state
- High availability
- TCP/IP cluster discovery
- JMX monitoring enabled
Prerequisites
- Java 17+, Maven 3.6+
Running Multiple Instances
Terminal 1 (Port 8080)
cd spring-boot-admin-samples/spring-boot-admin-sample-hazelcast
mvn spring-boot:run
Terminal 2 (Port 8081)
SERVER_PORT=8081 mvn spring-boot:run
Terminal 3 (Port 8082)
SERVER_PORT=8082 mvn spring-boot:run
All instances automatically form a cluster and share:
- Instance events
- Notification state
- Application registry
Dependencies
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
</dependency>
Hazelcast Configuration
@Bean
public Config hazelcastConfig() {
// Event store map - holds all instance events
MapConfig eventStoreMap = new MapConfig(DEFAULT_NAME_EVENT_STORE_MAP)
.setInMemoryFormat(InMemoryFormat.OBJECT)
.setBackupCount(1) // 1 backup copy
.setMergePolicyConfig(
new MergePolicyConfig(PutIfAbsentMergePolicy.class.getName(), 100)
);
// Notification map - deduplicates notifications
MapConfig sentNotificationsMap = new MapConfig(DEFAULT_NAME_SENT_NOTIFICATIONS_MAP)
.setInMemoryFormat(InMemoryFormat.OBJECT)
.setBackupCount(1)
.setEvictionConfig(
new EvictionConfig()
.setEvictionPolicy(EvictionPolicy.LRU)
.setMaxSizePolicy(MaxSizePolicy.PER_NODE)
);
Config config = new Config();
config.addMapConfig(eventStoreMap);
config.addMapConfig(sentNotificationsMap);
config.setProperty("hazelcast.jmx", "true");
// TCP/IP cluster discovery (local)
config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
TcpIpConfig tcpIpConfig = config.getNetworkConfig()
.getJoin()
.getTcpIpConfig();
tcpIpConfig.setEnabled(true);
tcpIpConfig.setMembers(singletonList("127.0.0.1"));
return config;
}
Configuration Details:
- Event Store: Reliable storage with 1 backup
- Sent Notifications: LRU eviction to prevent memory growth
- Cluster: TCP/IP discovery on localhost
- JMX: Enabled for monitoring
How Clustering Works
Event Synchronization
- Instance A receives status change event
- Event stored in Hazelcast distributed map
- Instances B and C immediately see the event
- All instances update their local state
Notification Deduplication
- Instance A sends notification
- Records in Hazelcast sent-notifications map
- Instance B sees event, checks sent-notifications
- B skips sending (already sent by A)
- No duplicate notifications to users
Load Balancing
Users can connect to any instance - they all show the same data.
Testing Clustering
Verify Cluster Formation
Check logs for:
Members {size:3, ver:3} [
Member [127.0.0.1]:5701 - e1f2g3h4
Member [127.0.0.1]:5702 - a5b6c7d8
Member [127.0.0.1]:5703 - i9j0k1l2
]
Test Event Sharing
- Register application on instance 8080
- Check instance 8081 - application appears
- Stop instance 8080
- Application still visible on 8081
Test High Availability
- Start 3 instances
- Stop instance 8080
- Instances 8081 and 8082 continue operating
- All data preserved (1 backup)
Production Configuration
Multicast Discovery
config.getNetworkConfig()
.getJoin()
.getMulticastConfig()
.setEnabled(true)
.setMulticastGroup("224.2.2.3")
.setMulticastPort(54327);
TCP/IP with Multiple Hosts
tcpIpConfig.setMembers(Arrays.asList(
"admin-1.company.com",
"admin-2.company.com",
"admin-3.company.com"
));
Kubernetes Discovery
config.getNetworkConfig()
.getJoin()
.getKubernetesConfig()
.setEnabled(true)
.setProperty("namespace", "default")
.setProperty("service-name", "spring-boot-admin");
Monitoring Hazelcast
JMX
Enable JMX and connect with JConsole:
jconsole
Look for com.hazelcast MBeans.
Hazelcast Management Center
docker run -p 8080:8080 hazelcast/management-center
Connect to: http://localhost:8080
Key Takeaways
✅ High Availability: No single point of failure
✅ Horizontal Scaling: Add instances dynamically
✅ Shared State: All instances synchronized
✅ Enterprise Features: Backup, eviction, merge policies