Curator实现分布式锁代码

Curator环境搭建
Maven依赖
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>4.2.0</version>
</dependency>
核心api配置
package com.shanhe.config;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.utils.CloseableUtils;
import org.springframework.stereotype.Component;

/**
 * zk框架实现分布式锁
 */
@Component
public class CuratorZkLock {


    // ZooKeeper 服务地址, 单机格式为:(127.0.0.1:2181),
    // 集群格式为:(127.0.0.1:2181)
    private String connectString;
    // Curator 客户端重试策略
    private RetryPolicy retry;
    // Curator 客户端对象
    private CuratorFramework client;

    public CuratorZkLock() throws Exception {
        init();
    }

    public void init() throws Exception {
        // 设置 ZooKeeper 服务地址为本机的 2181 端口
        connectString = "127.0.0.1:2181";
        // 重试策略
        // 初始休眠时间为 1000ms, 最大重试次数为 3
        retry = new ExponentialBackoffRetry(1000, 3);
        // 创建一个客户端, 60000(ms)为 session 超时时间, 15000(ms)为连接超时时间
        client = CuratorFrameworkFactory.newClient(connectString, 60000, 15000, retry);
        client.start();
    }

    public void close() {
        CloseableUtils.closeQuietly(client);
    }

    public CuratorFramework getClient() {
        return client;
    }
}
简单用法 
package com.shanhe.service;

import com.shanhe.config.CuratorZkLock;
import com.shanhe.entity.CommodityDetails;
import com.shanhe.mapper.CommodityDetailsMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;

@RestController
@Slf4j
public class SeckillService {
    @Autowired
    private CuratorZkLock curatorZkLock;
    // ZooKeeper 锁节点路径, 分布式锁的相关操作都是在这个节点上进行
    private final String lockPath = "/distributed-lock";
    @Autowired
    private CommodityDetailsMapper commodityDetailsMapper;

    /**
     * 秒杀lock
     *
     * @return
     */
    @RequestMapping("/seckilLock")
    public String seckilLock() throws Exception {
        InterProcessMutex interProcessMutex = null;
        try {
            CuratorFramework client = curatorZkLock.getClient();
            // 获取锁 底层 zk上创建一个临时顺序编号节点
            interProcessMutex = new InterProcessMutex(client, lockPath);
            //获取锁 一直没有获取锁成功的情况下,默认是会阻塞。
            interProcessMutex.acquire();
            log.info("<获取锁成功....>");
            log.info("<执行秒杀扣库存业务逻辑....>");
            CommodityDetails commodityDetails = commodityDetailsMapper.getCommodityDetails(1L);
            Long stock = commodityDetails.getStock();
            if (stock > 0) {
                log.info("<开始执行扣库存..>");
                int result = commodityDetailsMapper.reduceInventory(1l);
                return result > 0 ? "扣库存成功" : "扣库存失败";
            }
            // 扣库存失败
            log.info("<扣库存失败>");
            return "fail";

        } catch (Exception e) {
            e.printStackTrace();
            log.error("<秒杀出现错误:e:{}>", e);
            return "fail";
        } finally {
            // 释放锁
            if (interProcessMutex != null)
                interProcessMutex.release();
        }

    }


}

 

posted @ 2023-02-07 17:39  山河永慕~  阅读(66)  评论(0编辑  收藏  举报