SpringBoot使用Zookeeper实现分布式锁的实现示例

 更新时间:2025年10月22日 16:05:27   作者:小猿、  
Zookeeper是一个分布式协调服务,非常适合用来实现分布式锁,下面我将介绍如何在Spring Boot项目中集成Zookeeper来实现分布式锁,_springboot实现基于zk的分布式锁

概述

Zookeeper是一个分布式协调服务,非常适合用来实现分布式锁。下面我将介绍如何在Spring Boot项目中集成Zookeeper来实现分布式锁。

1. 添加依赖

首先,在pom.xml中添加必要的依赖:

<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.7.0</version>
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>5.2.0</version>
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>5.2.0</version>
</dependency>

2. 配置Zookeeper连接

application.propertiesapplication.yml中配置Zookeeper连接信息:

# Zookeeper配置
zookeeper.address=localhost:2181
zookeeper.session-timeout=5000
zookeeper.connection-timeout=5000

3. 创建Zookeeper配置类

@Configuration
public class ZookeeperConfig {

    @Value("${zookeeper.address}")
    private String connectString;

    @Value("${zookeeper.session-timeout}")
    private int sessionTimeout;

    @Value("${zookeeper.connection-timeout}")
    private int connectionTimeout;

    @Bean
    public CuratorFramework curatorFramework() {
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString(connectString)
                .sessionTimeoutMs(sessionTimeout)
                .connectionTimeoutMs(connectionTimeout)
                .retryPolicy(retryPolicy)
                .build();
        client.start();
        return client;
    }
}

4. 实现分布式锁工具类

@Component
public class ZookeeperDistributedLock {

    private final CuratorFramework client;

    private static final String LOCK_ROOT_PATH = "/locks";

    public ZookeeperDistributedLock(CuratorFramework client) {
        this.client = client;
    }

    /**
     * 获取互斥锁
     * @param lockPath 锁路径
     * @param timeout 超时时间(毫秒)
     * @return 锁对象
     */
    public InterProcessMutex acquireMutex(String lockPath, long timeout) throws Exception {
        String path = LOCK_ROOT_PATH + "/" + lockPath;
        InterProcessMutex mutex = new InterProcessMutex(client, path);
        
        if (mutex.acquire(timeout, TimeUnit.MILLISECONDS)) {
            return mutex;
        }
        return null;
    }

    /**
     * 释放锁
     * @param mutex 锁对象
     */
    public void releaseMutex(InterProcessMutex mutex) {
        try {
            if (mutex != null && mutex.isAcquiredInThisProcess()) {
                mutex.release();
            }
        } catch (Exception e) {
            throw new RuntimeException("释放锁失败", e);
        }
    }
}

5. 使用分布式锁

在业务代码中使用分布式锁:

@Service
public class OrderService {

    @Autowired
    private ZookeeperDistributedLock distributedLock;

    public void createOrder() {
        InterProcessMutex lock = null;
        try {
            // 获取锁,设置超时时间5秒
            lock = distributedLock.acquireMutex("order-create", 5000);
            if (lock != null) {
                // 获取锁成功,执行业务逻辑
                System.out.println("获取锁成功,开始处理业务");
                // 模拟业务处理
                Thread.sleep(2000);
                System.out.println("业务处理完成");
            } else {
                System.out.println("获取锁失败,可能有其他实例正在处理");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 释放锁
            if (lock != null) {
                distributedLock.releaseMutex(lock);
            }
        }
    }
}

6. 测试分布式锁

可以启动多个Spring Boot实例来测试分布式锁的效果:

@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @GetMapping("/create")
    public String createOrder() {
        orderService.createOrder();
        return "订单创建请求已提交";
    }
}

实现原理说明

临时顺序节点:Zookeeper的分布式锁实际上是利用了临时顺序节点的特性

锁获取

  • 每个客户端在指定的锁路径下创建临时顺序节点
  • 判断自己创建的节点是否是当前最小的节点,如果是则获取锁
  • 如果不是则监听前一个节点的删除事件

锁释放

  • 任务完成后删除自己创建的节点
  • 下一个节点会收到通知并获取锁

注意事项

  • 连接管理:确保Zookeeper客户端连接的正确管理和异常处理
  • 锁超时:设置合理的锁超时时间,避免死锁
  • 锁释放:务必在finally块中释放锁,防止锁泄漏
  • 重试机制:网络不稳定时需要有合理的重试机制
  • 锁粒度:根据业务需求设计合理的锁粒度

以上实现使用了Curator框架,它封装了Zookeeper的复杂操作,提供了更简单易用的API,特别是它的InterProcessMutex类已经实现了分布式锁的核心逻辑。

到此这篇关于SpringBoot使用Zookeeper实现分布式锁的实现示例的文章就介绍到这了,更多相关SpringBoot Zookeeper分布式锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • springBoot接入阿里云oss的实现步骤

    springBoot接入阿里云oss的实现步骤

    这篇文章主要介绍了springBoot接入阿里云oss的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • springboot项目中的bootstrap.yml配置不生效的原因及解决(没有自动提示)

    springboot项目中的bootstrap.yml配置不生效的原因及解决(没有自动提示)

    新创建一个 springboot项目,添加了 bootstrap.yml 文件,发现文件并没有如预期变成绿色叶子,编写的时候也没有自动提示,启动的时候,发现端口是8080,由此发现配置并没有生效,所以本文给大家讲解了springboot项目中的bootstrap.yml配置不生效的原因及解决
    2024-01-01
  • SpringBoot 添加JSP 支持并附带在IDEA下创建JSP文件【测试无误】

    SpringBoot 添加JSP 支持并附带在IDEA下创建JSP文件【测试无误】

    这篇文章主要介绍了SpringBoot 添加JSP 支持并附带在IDEA下创建JSP文件的相关知识,感兴趣的朋友跟随脚本之家小编一起学习吧
    2018-05-05
  • SpringBoot公共模块配置方式

    SpringBoot公共模块配置方式

    这篇文章主要介绍了SpringBoot公共模块配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • java中servlet实现登录验证的方法

    java中servlet实现登录验证的方法

    做web开发,登录验证是免不了的,今天学习了servlet的登录验证,当然是很简单的,没有使用session,request等作用域对象,所以还是可以直接通过地址访问网页的。
    2013-05-05
  • springboot Actuator的指标监控可视化功能详解

    springboot Actuator的指标监控可视化功能详解

    SpringBoot Actuator是springboot为简化我们对微服务项目的监控功能抽取出来的模块,使得我们每个微服务快速引用即可获得生产界别的应用监控、审计等功能。这篇文章主要介绍了springboot Actuator的指标监控可视化,需要的朋友可以参考下
    2021-08-08
  • SpringBoot连接MySql数据库的原理及代码示例

    SpringBoot连接MySql数据库的原理及代码示例

    SpringBoot是一款流行的Java开发框架,它可以轻松地连接各种类型的数据库,包括关系型数据库和非关系型数据库,本文将介绍SpringBoot是如何连接数据库的,包括其原理和代码示例,需要的朋友可以参考下
    2023-07-07
  • Java中的ReadWriteLock读写锁详解

    Java中的ReadWriteLock读写锁详解

    这篇文章主要介绍了Java中的ReadWriteLock读写锁详解,ReadWriteLock也是一个接口,提供了readLock和writeLock两种锁的操作机制,一个资源可以被多个线程同时读,或者被一个线程写,但是不能同时存在读和写线程,需要的朋友可以参考下
    2023-12-12
  • SpringBoot使用@valid进行参数校验的流程步骤

    SpringBoot使用@valid进行参数校验的流程步骤

    SpringBoot 提供了一种方便的方式来进行参数校验:使用 Hibernate Validator,Spring Boot 提供了一种方便的方式来进行参数校验:使用 Hibernate Validator,所以本文给大家介绍了SpringBoot使用@valid进行参数校验的流程步骤,需要的朋友可以参考下
    2023-09-09
  • 解决java启动时报线程占用报错:Exception in thread “Thread-14“ java.net.BindException: Address already in use: bind

    解决java启动时报线程占用报错:Exception in thread “Thread-14“ java.ne

    这篇文章主要给大家介绍了关于解决java启动时报线程占用:Exception in thread “Thread-14“ java.net.BindException: Address already in use: bind的相关资料,文中将解决的办法介绍的非常详细,需要的朋友可以参考下
    2023-04-04

最新评论