Spring Boot整合Hazelcast后,应用实例可以组成一个分布式内存网格,所有节点上的数据结构和计算资源形成一个逻辑整体。与传统的Redis或Memcached独立缓存服务不同,Hazelcast以嵌入式库的方式运行在JVM内部,不依赖额外的服务进程,同时又提供分布式Map、Queue、Topic、Lock等多种数据结构。这使得它在微服务环境中非常适合承担共享会话、分布式锁、配置分发和实时计算等职责。

一、Hazelcast与Spring Boot整合基础
Hazelcast的核心是一个可以嵌入到Java应用中的内存数据网格。每个运行Hazelcast的Spring Boot实例都称为一个成员节点,多个成员节点通过组网协议自动发现并组成集群。集群形成后,数据会按照分区算法分布在各个节点上,默认每个数据条目会有一个备份,以保证节点故障时数据不丢失。Spring Boot通过自动配置简化了Hazelcast实例的创建,只需引入依赖并在配置文件中指定集群参数即可。
首先在Maven工程的pom.xml中加入Hazelcast与Spring Boot的起步依赖。如果项目已经引入了Spring Cache抽象,还可以通过Hazelcast实现缓存管理器。依赖配置如下:
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-spring</artifactId>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
</dependency>
如果使用Spring Boot 2.x或更高版本,还可以直接引入hazelcast-spring-boot-starter,但需要注意该模块可能不包含在核心Hazelcast中。基础依赖加入后,Spring容器会自动探测到Hazelcast的配置文件。如果没有提供显式的HazelcastInstance配置Bean,Spring Boot会读取classpath下的hazelcast.xml或hazelcast.yaml,也可以完全使用Java配置。
接着创建一个配置类来定义Hazelcast实例。下面的代码通过Java配置方式设置了集群名称、网络端口和成员发现策略。使用JoinConfig可以指定TCP/IP静态成员列表或组播方式。对于容器化部署,通常使用TCP/IP并列出所有节点的地址。
import com.hazelcast.config.Config;
import com.hazelcast.config.JoinConfig;
import com.hazelcast.config.NetworkConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HazelcastConfig {
@Bean
public Config hazelcastConfig() {
Config config = new Config();
config.setClusterName("spring-boot-hazelcast");
NetworkConfig network = config.getNetworkConfig();
network.setPort(5701).setPortAutoIncrement(true);
JoinConfig join = network.getJoin();
join.getMulticastConfig().setEnabled(false);
join.getTcpIpConfig()
.setEnabled(true)
.addMember("192.168.1.10")
.addMember("192.168.1.11")
.addMember("192.168.1.12");
return config;
}
}
生产环境中更推荐使用Hazelcast的自动发现机制,例如基于Kubernetes API或AWS EC2的发现插件,避免手工维护IP列表。无论哪种方式,只要两个节点的集群名和网络配置匹配,它们就会自动建立连接并开始共享状态。此时,通过注入HazelcastInstance即可访问分布式数据结构。
二、核心分布式数据结构与计算能力
Hazelcast提供了多种分布式数据结构,最常用的是IMap。它实现java.util.concurrent.ConcurrentMap接口,但数据并不在单个JVM堆中,而是分布在整个集群的节点上。使用IMap时,每个键通过哈希计算被分配到固定分区,Spring Boot节点只负责存储部分分区的主数据或备份数据。这种设计让读写请求可以在任意节点发起,Hazelcast内部会根据键的路由将操作转发到对应分区的主节点执行。
下面是一个简单的分布式缓存服务示例。通过HazelcastInstance获取IMap并向其中写入数据。与本地HashMap不同,写入的数据会立即在集群其他节点上可见,不需要额外的同步代码。
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import org.springframework.stereotype.Service;
@Service
public class DistributedCacheService {
private final IMap<String, String> cache;
public DistributedCacheService(HazelcastInstance hazelcastInstance) {
this.cache = hazelcastInstance.getMap("user-cache");
}
public void put(String key, String value) {
cache.put(key, value);
}
public String get(String key) {
return cache.get(key);
}
}
除了IMap,分布式计算还经常使用IExecutorService、ITopic和ISet等结构。IExecutorService允许将Callable任务提交到集群中拥有指定键的成员上执行,适合数据本地化计算。例如,当需要处理某个用户的订单数据时,可以把任务路由到该用户数据所在节点,减少网络传输。下面是一个简单的任务执行示例。
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IExecutorService;
import java.io.Serializable;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
public class OrderTotalTask implements Callable<Double>, Serializable {
private final String orderId;
public OrderTotalTask(String orderId) {
this.orderId = orderId;
}
@Override
public Double call() throws Exception {
// 从本地分区读取订单明细并计算总额
return 199.0;
}
}
// 在业务层中执行
@Service
public class OrderService {
private final IExecutorService executor;
public OrderService(HazelcastInstance instance) {
this.executor = instance.getExecutorService("order-executor");
}
public Double computeTotal(String orderId) throws Exception {
Future<Double> future = executor.submit(new OrderTotalTask(orderId));
return future.get();
}
}
ITopic则提供了发布订阅能力,适合实现集群内的事件广播。当某个节点修改了共享配置后,可以向Topic发布消息,其他节点订阅后实时刷新本地缓存。ISet可以用于维护全局唯一的列表,例如当前在线用户ID集合。这些数据结构共同构成了Hazelcast作为分布式内存网格的计算基础。
三、集群配置、高可用与常见问题
Hazelcast的集群高可用依赖分区备份和节点发现。默认情况下,每个分区有一个备份,即数据在集群中保存两份。如果某个节点宕机,Hazelcast会自动将备份分区提升为主分区,并在剩余节点上创建新的备份,整个过程对应用透明。备份数量可以通过配置修改,例如设置backup-count为2可以容忍两台节点同时故障,但会增加内存和网络开销。
节点发现机制的选择对集群稳定性至关重要。开发环境可以使用组播,因为不需要额外配置;但在云环境和容器网络中,组播通常被禁止,这时应启用TCP/IP发现并配置成员列表。Kubernetes环境下推荐使用Hazelcast Kubernetes插件,通过API自动发现Pod。配置示例中需要关闭组播、开启TCP/IP并添加成员,也可以使用端口递增策略,让同一主机上的多个实例自动探测相邻端口。
在使用过程中,开发者常遇到的一个问题是节点无法组成集群。排查时首先要检查集群名称是否一致,其次确认端口是否被防火墙拦截。默认端口5701可以自动递增,但如果只允许固定端口,需要设置portAutoIncrement为false。另一个常见问题是序列化异常,因为Hazelcast需要将对象序列化后存储到网络。Java原生序列化虽然简单但性能较差,建议使用DataSerializable或Kryo等序列化方式。对于复杂对象,最好定义显式的序列化工厂,避免反序列化时版本不一致。
此外,Hazelcast还可以与Spring Cache抽象结合,通过在方法上添加@Cacheable、@CacheEvict等注解实现声明式缓存。启用Spring Cache时,Hazelcast会自动创建一个CacheManager,底层仍然使用IMap存储数据。但要注意缓存的数据应尽量是可重复计算的结果,而不是强一致性的业务状态,否则需要考虑锁和事务问题。Hazelcast也提供分布式锁ILock,可以在跨节点的临界区中保证互斥,但使用时要设置合理的超时时间,避免死锁。
总结来说,Spring Boot整合Hazelcast可以让应用无需独立中间件就获得分布式内存网格能力,适合中小规模集群和微服务架构。它弥补了本地缓存的单节点限制,同时比引入Redis等外部服务更轻量。不过在实际生产中,仍需关注网络分区、序列化性能和备份策略,才能充分发挥其分布式计算优势。
Spring BootHazelcast分布式内存网格修改时间:2026-08-28 20:13:39