在开发高并发系统时,我们经常需要控制多个执行单元对同一个资源的访问,避免出现数据不一致。当系统从单机走向集群,锁的选择也发生了变化。本地并发锁只能管住一个进程内的线程,而跨服务器资源锁要解决的是多个物理节点之间的互斥问题,这就是分布式锁存在的意义。

什么是本地并发锁
本地并发锁是指运行在单个应用进程内部的同步机制,典型实现有 Java 的 synchronized 关键字和 ReentrantLock。它们依赖 JVM 层面的监视器或 AQS 队列,只能限制同一个进程里的多个线程同时进入临界区。
// 使用 ReentrantLock 保护本地资源
import java.util.concurrent.locks.ReentrantLock;
public class LocalCounter {
private final ReentrantLock lock = new ReentrantLock();
private int count = 0;
public void increment() {
lock.lock(); // 获取本地锁
try {
count++; // 临界区操作
} finally {
lock.unlock(); // 释放本地锁
}
}
}
什么是分布式锁
分布式锁是一种跨进程、跨服务器的协调机制,通常借助外部中间件实现,例如 Redis、ZooKeeper 或数据库。它的目标是让不同机器上的服务在访问共享资源时,只有一个节点能成功获得锁。
import redis
# 使用 Redis 实现简单分布式锁
r = redis.Redis(host='127.0.0.1', port=6379, db=0)
def acquire_lock(lock_name, expire=10):
# setnx 仅当 key 不存在时设置,返回是否成功
return r.set(lock_name, '1', nx=True, ex=expire)
def release_lock(lock_name):
r.delete(lock_name)
if acquire_lock('order_lock'):
try:
# 处理跨服务器共享订单资源
pass
finally:
release_lock('order_lock')
本地并发锁与跨服务器资源锁的核心区别
| 对比维度 | 本地并发锁 | 跨服务器资源锁(分布式锁) |
|---|---|---|
| 作用范围 | 单进程内线程间 | 多进程、多服务器节点间 |
| 实现依赖 | 语言或虚拟机内置 | 外部协调服务或存储中间件 |
| 网络开销 | 无 | 有,受网络延迟影响 |
| 失效场景 | 进程重启即失效 | 中间件故障可能导致锁不可用 |
为什么本地锁在集群中不够用
假设订单服务部署在两台服务器上,每台机器用本地锁保护库存扣减。用户请求被负载均衡到不同节点,两个节点同时执行扣减,本地锁互不感知,最终库存可能出现超卖。此时必须使用跨服务器资源锁,让所有节点竞争同一把锁。
选型建议
- 纯单机应用或定时任务:使用本地并发锁,简单且性能好。
- 微服务集群、共享数据库或缓存:使用分布式锁,保证全局互斥。
- 对一致性要求极高:优先考虑 ZooKeeper 或 etcd 实现的锁。
注意:分布式锁不是银弹,需设置合理的过期时间并处理误删问题,否则可能引发新的并发隐患。
小结
理解本地并发锁与跨服务器资源锁的区别,是设计稳定并发系统的第一步。根据部署形态选择恰当的锁机制,才能既保障安全又兼顾效率。