接触过的分布式框架与分布式锁实现
分布式和分布式锁经常连着问。根据自己简历上写过的栈答,别罗列没碰过的组件;下面以国内常见的 Spring Cloud Alibaba 为主线,锁以 Redis 为例(项目里最常见)。
题目
- 分布式框架接触过哪些?
- 分布式锁怎么实现?
参考答案(口述要点)
框架:Nacos(注册/配置)、OpenFeign、Gateway、Sentinel(限流熔断)、Seata(分布式事务,若有);老项目可能还有 Eureka、Zuul。
分布式锁:RedisSET key value NX EX、Redisson;ZK 临时顺序节点;数据库悲观锁性能差一般不当首选。
详细解析:分布式框架(按层说)
| 能力 | 常用组件 | 干什么 |
|---|---|---|
| 注册发现 | Nacos、Eureka | 服务上下线、健康检查 |
| 配置中心 | Nacos Config | 动态改配置、少重启 |
| 网关 | Spring Cloud Gateway | 路由、鉴权、限流入口 |
| 调用 | OpenFeign + LoadBalancer | 声明式 HTTP、负载均衡 |
| 容错 | Sentinel | 限流、熔断、降级 |
| 事务 | Seata | 跨服务 AT/TCC(有成本,慎用) |
| 消息 | RocketMQ / Kafka | 异步、削峰 |
Feign 调用示例
@FeignClient(name = "order-service", path = "/api/order")
public interface OrderClient {
@GetMapping("/{id}")
OrderDTO get(@PathVariable("id") Long id);
}面试时说清:消费者通过服务名从 Nacos 拿实例列表,Ribbon/LoadBalancer 选一个 IP 调用。
详细解析:分布式锁
要满足:互斥、同进程可重入(可选)、锁超时防死、高可用。
Redis 单节点(简单,有极端宕机风险)
// 加锁:NX + 过期时间必须一起,防死锁
Boolean ok = redis.set("lock:order:" + orderId, uuid, SetArgs.Builder.nx().ex(30));
if (Boolean.TRUE.equals(ok)) {
try {
// 业务
} finally {
// 删锁要校验 value 是自己,防误删别人锁
String script =
"if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
redis.eval(script, List.of("lock:order:" + orderId), List.of(uuid));
}
}Redisson(项目更省事)
RLock lock = redisson.getLock("lock:order:" + orderId);
if (lock.tryLock(5, 30, TimeUnit.SECONDS)) {
try {
// 业务
} finally {
if (lock.isHeldByCurrentThread()) lock.unlock();
}
}看门狗会自动续期,适合执行时间不确定的任务。
和本地锁区别:多实例部署时 synchronized 只管一个 JVM,扣库存、防重复下单 必须上分布式锁或 DB 唯一约束。
代码与实践
- 锁粒度:
lock:业务:业务id,别一把大锁锁全表。 - 能不用锁就不用:订单号唯一索引 + 幂等表,有时比锁稳。
- Redis 主从切换:旧版主从异步复制可能丢锁,金融级要问 Redisson 红锁或 ZooKeeper。
写在最后
简历上没写过的中间件别硬吹;分布式锁答完 Redis 方案,提一句 「我们还在 DB 层做了唯一约束双保险」 很加分。
创作不易,转载请注明出处和作者。
