这段内容是关于 Apache Ignite 中 分布式信号量(Distributed Semaphore) 的说明和使用示例。我们来一步步解析,帮助你深入理解它的含义和用途。
🔹 一、什么是 Semaphore(信号量)?
在并发编程中,Semaphore(信号量) 是一种经典的同步工具,用于控制对共享资源的并发访问数量。
- 它内部维护一组“许可”(permits)。
- 线程可以通过
acquire()
方法获取一个许可(如果还有空闲许可),否则会阻塞等待。 - 使用完资源后,通过
release()
方法归还许可,供其他线程使用。
👉 Java 标准库中的例子:
java.util.concurrent.Semaphore semaphore = new Semaphore(3); // 最多允许3个线程同时访问
semaphore.acquire(); // 获取许可
try {// 执行临界区代码
} finally {semaphore.release(); // 释放许可
}
这限制了同一时间最多只有 3 个线程能进入临界区。
🔹 二、Ignite 的分布式信号量是什么?
标准的 java.util.concurrent.Semaphore
只能在单个 JVM 内部起作用。
而 Ignite 的 IgniteSemaphore
是分布式的,意味着:
✅ 它可以在 整个集群的所有节点之间共享和协调,实现跨 JVM、跨机器的资源访问控制。
🌐 应用场景举例:
假设你有一个分布式系统,部署在 5 台服务器上(5 个 Ignite 节点),你想:
- 同一时间最多只有 2 个节点可以访问某个外部服务(如数据库、API 接口等)。
- 或者限制同时执行某项高负载任务的节点数量。
这时就可以用 IgniteSemaphore
来实现集群级别的“限流”或“互斥”。
🔹 三、代码详解
Ignite ignite = Ignition.start();IgniteSemaphore semaphore = ignite.semaphore("semName", // 信号量的名字(全局唯一标识)20, // 初始许可数量:最多20个并发许可true, // 是否自动释放:如果持有许可的节点宕机或退出集群,是否自动回收其持有的许可?true // 如果不存在,是否自动创建?
);
参数解释:
参数 | 说明 |
---|---|
"semName" | 所有节点通过这个名字找到同一个分布式信号量 |
20 | 最多允许 20 个节点/线程同时持有许可 |
true (failoverEnabled) | 若某个节点崩溃,它之前 acquire 的许可会被自动释放,避免死锁 |
true (create) | 如果这个信号量还没创建过,就新建一个;否则获取已存在的 |
🔹 四、使用示例分析
// 获取信号量实例
IgniteSemaphore semaphore = ignite.semaphore("semName", 20, true, true);// 获取一个许可(如果没有可用许可,会阻塞等待)
semaphore.acquire();try {// 此时当前节点已获得许可,可以安全执行受限操作ignite.compute().run(() -> {System.out.println("Executed on:" + ignite.cluster().localNode().id());// 比如调用外部服务、写文件、处理大数据等});
} finally {// 一定要释放许可,否则其他节点永远等不到semaphore.release();
}
✅ 这段代码可以在多个节点上并发运行,但最多只有 20 个节点能同时进入 try 块执行任务。
🔹 五、关键特性总结
特性 | 说明 |
---|---|
✅ 分布式 | 跨多个节点共享状态,所有节点看到的是同一个信号量 |
✅ 高可用 | 支持节点故障时自动回收许可(设置 failoverEnabled=true ) |
✅ 可重入? | ❌ IgniteSemaphore 不支持可重入(不像锁那样可重复进入) |
✅ 持久化? | 否,它是内存中的协调机制,重启后状态丢失(除非你自己持久化) |
🔹 六、常见用途
- 限流控制:限制同时访问某个外部系统的请求数。
- 分布式任务调度:确保同一时间只有 N 个节点执行某类任务。
- 资源池管理:比如只允许最多 5 个节点连接到某台旧设备。
- 协调批量作业:防止所有节点同时执行耗时任务导致雪崩。
🔹 七、注意事项
- 获取许可后必须释放(建议用 try-finally)。
- 许可数量要合理设置,太小会导致性能瓶颈,太大失去意义。
- 如果
failoverEnabled=false
,某个节点挂了且没释放许可,可能导致其他节点永远阻塞。 IgniteSemaphore
是基于集群通信实现的,有一定网络开销,不适合超高频调用。
✅ 总结一句话:
Ignite 的
IgniteSemaphore
就像是 Java 标准库中Semaphore
的“分布式升级版”,让你可以在整个集群范围内控制并发访问的数量,实现跨节点的流量控制与资源协调。
如果你正在构建一个分布式系统,并需要“集群级别的限流”或“协同执行”,那么 IgniteSemaphore
是一个非常实用的工具。