使用ZooKeeper原生API实现分布式锁

本文通过一个秒杀场景展示了分布式锁的必要性。使用ZooKeeper的临时顺序节点和事件监听机制,详细讲解如何实现分布式锁,避免在高并发环境下出现库存超卖的问题。并进行了压力测试,验证了方案的有效性。
摘要由CSDN通过智能技术生成

分布式锁的引入

一个很典型的秒杀场景,或者说并发量非常高的场景下,对商品库存的操作,我用一个SpringBoot小项目模拟一下。

用到的技术知识:

  • SpringBoot
  • Redis
  • ZooKeeper

我提前将库存 stock 放在redis,初始值为288:

127.0.0.1:6379> set stock 288
OK
127.0.0.1:6379> get stock
"288"
复制代码

扣减库存的api:

@RequestMapping("/v1/reduce")
public String reduceStock() {
    String stockStr = redisTemplate.opsForValue().get("stock");
    int stock = Integer.parseInt(stockStr);
    if (stock > 0) {
        int realStock = stock - 1;
        redisTemplate.opsForValue().set("stock", String.valueOf(realStock));
        System.out.println(Thread.currentThread().getName() + " 减库存成功,剩余库存:" + realStock);
    } else {
        System.out.println("不能再减了,没有库存了!");
    }
    return port + ": reduce stock end";
}
复制代码

单机环境下的高并发:

我用 Apache JMeter 模拟在同一时刻,有 500 个请求打到 /stock/v1/reduce 上进行减库存的操作:

Apache JMeter是Apache组织开发的基于Java的压力测试工具。用它很容易模拟出高并发场景。

Apache JMeter官网: jmeter.apache.org/download_jm…

启动SpringBoot项目,执行压测,运行结果:

500个并发,才扣减了5个!!!BOSS该找你事了!

不过这种情况我们程序员是不会让它出现的,加个 synchronized ,让每个线程拿到锁之后再去扣减库存:

代码实现:

@RequestMapping("/v2/reduce")
public String reduceStockV2() {
    //加线程同步
    synchronized (this) {
        String stockStr = redisT
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值