springboot+zookeeper实现分布式锁


Posted in Java/Android onMarch 21, 2022

springboot+zookeeper实现分布式锁

InterProcessMutex内部实现了zookeeper分布式锁的机制,所以接下来我们尝试使用这个工具来为我们的业务加上分布式锁处理的功能

zookeeper分布式锁的特点:1、分布式 2、公平锁 3、可重入

依赖

<dependency>
   <groupId>org.apache.zookeeper</groupId>
   <artifactId>zookeeper</artifactId>
   <version>3.4.10</version>
</dependency>
<!-- zookeeper 客户端 -->
<dependency>
   <groupId>org.apache.curator</groupId>
   <artifactId>curator-framework</artifactId>
   <version>2.12.0</version>
</dependency>
<dependency>
   <groupId>org.apache.curator</groupId>
   <artifactId>curator-recipes</artifactId>
   <version>2.12.0</version>
</dependency>
<!-- lombok -->
<dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <version>1.18.16</version>
   <scope>provided</scope>
</dependency>

本地封装

这个工具类主要封装CuratorFramework这个client(连接Zookeeper)

@Slf4j
public class CuratorClientUtil {
    private String zookeeperServer;

    @Getter
    private CuratorFramework client;

    public CuratorClientUtil(String zookeeperServer) {
        this.zookeeperServer = zookeeperServer;
    }

  	// 创建CuratorFrameworkFactory并且启动
    public void init() {
       // 重试策略,等待1s,最大重试3次
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3);
        this.client = CuratorFrameworkFactory.builder()
                .connectString(zookeeperServer)
                .sessionTimeoutMs(5000)
                .connectionTimeoutMs(5000)
                .retryPolicy(retryPolicy)
                .build();
        this.client.start();
    }

   // 容器关闭,CuratorFrameworkFactory关闭
    public void destroy() {
        try {
            if (Objects.nonNull(getClient())) {
                getClient().close();
            }
        } catch (Exception e) {
            log.info("CuratorFramework close error=>{}", e.getMessage());
        }
    }
}

配置

@Configuration
public class CuratorConfigration {
    @Value("${zookeeper.server}")
    private String zookeeperServer;
    // 注入时,指定initMethod和destroyMethod
    @Bean(initMethod = "init", destroyMethod = "destroy")
    public CuratorClientUtil curatorClientUtil() {
        CuratorClientUtil clientUtil = new CuratorClientUtil(zookeeperServer);
        return clientUtil;
    }
}

测试代码

模拟不同客户端的请求

@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {
    // 注入client工具类
    @Autowired
    private CuratorClientUtil curatorClientUtil;
    // 在zookeeper的/rootLock节点下创建锁对应的临时有序节点
    private String rootLock = "/rootLock";

    @GetMapping("/testLock")
    public Object testLock() throws Exception {
        // 获取当前线程的名字,方便观察那些线程在获取锁
        String threadName = Thread.currentThread().getName();
        InterProcessMutex mutex = new InterProcessMutex(curatorClientUtil.getClient(), rootLock);
        try {
            log.info("{}---获取锁start", threadName);
            // 尝试获取锁,最长等待3s,超时放弃获取
            boolean lockFlag = mutex.acquire(3000, TimeUnit.SECONDS);
            // 获取锁成功,进行业务处理
            if (lockFlag) {
                log.info("{}---获取锁success", threadName);
                // 模拟业务处理,时间为3s
                Thread.sleep(3000);
            } else {
                log.info("{}---获取锁fail", threadName);
            }
        } catch (Exception e) {
            log.info("{}---获取锁异常", threadName);
        } finally {
            // 业务处理完成,释放锁,唤醒比当前线程创建的节点序号大(最靠近)的线程获取锁
            mutex.release();
            log.info("{}---锁release", threadName);
        }
        return "线程:" + threadName + "执行完成";
    }
}

JMeter测试

我们使用JMeter模拟100个客户端同时并发的访问 localhost:8081/test/testLock,相当于100个客户端争抢分布式锁,结果如图右上角所示,100个请求花了5分6s,每个线程获取到锁后业务处理3s,100个线程理想时间为300s(Thread.sleep(3000)),所以运行时间符合。
springboot+zookeeper实现分布式锁springboot+zookeeper实现分布式锁

zookeeper每个线程在/rooLock节点下创建的临时有序节点如下图,由于是临时的,所以线程释放锁后这些节点也会删除
springboot+zookeeper实现分布式锁
100个线程程序日志打印
springboot+zookeeper实现分布式锁

关于InterProcessMutex内部如何实现zookeeper分布式锁,请看我写的这篇文章:在这里

Java/Android 相关文章推荐
一篇带你入门Java垃圾回收器
Jun 16 Java/Android
详解Java实践之适配器模式
Jun 18 Java/Android
SpringCloud Alibaba项目实战之nacos-server服务搭建过程
Jun 21 Java/Android
Java中PriorityQueue实现最小堆和最大堆的用法
Jun 27 Java/Android
java解析XML详解
Jul 09 Java/Android
springboot 多数据源配置不生效遇到的坑及解决
Nov 17 Java/Android
SpringDataJPA实体类关系映射配置方式
Dec 06 Java/Android
SpringBoot2零基础到精通之数据与页面响应
Mar 22 Java/Android
Netty客户端接入流程NioSocketChannel创建解析
Mar 25 Java/Android
Spring依赖注入多种类型数据的示例代码
Mar 31 Java/Android
Java界面编程实现界面跳转
Jun 16 Java/Android
Java 多线程并发FutureTask
Jun 28 Java/Android
Mybatis-Plus进阶分页与乐观锁插件及通用枚举和多数据源详解
Mar 21 #Java/Android
Spring this调用当前类方法无法拦截的示例代码
SpringCloud Feign请求头删除修改的操作代码
Mar 20 #Java/Android
JavaWeb实现显示mysql数据库数据
关于Mybatis中SQL节点的深入解析
springboot 自定义配置 解决Boolean属性不生效
Mar 18 #Java/Android
使用Java去实现超市会员管理系统
Mar 18 #Java/Android
You might like
php桌面中心(一) 创建数据库
2007/03/11 PHP
php安装xdebug/php安装pear/phpunit详解步骤(图)
2013/12/22 PHP
[企业公众号]升级到[企业微信]之后发送消息失败的解决方法
2017/06/30 PHP
PHP实现的自定义图像居中裁剪函数示例【测试可用】
2017/08/11 PHP
CodeIgniter框架实现的整合Smarty引擎DEMO示例
2019/03/28 PHP
PHP中-&gt;和=&gt;的含义及使用示例解析
2020/08/06 PHP
javascript 写类方式之二
2009/07/05 Javascript
基于jQuery的仿flash的广告轮播
2010/11/05 Javascript
jquery实现可点击伸缩与展开的菜单效果代码
2015/08/31 Javascript
jQuery实现为控件添加水印文字效果(附源码)
2015/12/02 Javascript
jQuery弹出遮罩层效果完整示例
2016/09/13 Javascript
Angular中使用ui router实现系统权限控制及开发遇到问题
2016/09/23 Javascript
JavaScript箭头(arrow)函数详解
2017/06/04 Javascript
js 事件的传播机制(实例讲解)
2017/07/20 Javascript
谈谈为什么你的 JavaScript 代码如此冗长
2019/01/30 Javascript
vue项目首屏打开速度慢的解决方法
2019/03/31 Javascript
使用Vue 实现滑动验证码功能
2019/06/27 Javascript
express框架下使用session的方法
2019/07/31 Javascript
vue实现侧边栏导航效果
2019/10/21 Javascript
vue 项目打包时样式及背景图片路径找不到的解决方式
2019/11/12 Javascript
Vue实现手机扫描二维码预览页面效果
2020/05/28 Javascript
Python利用ansible分发处理任务
2015/08/04 Python
使用Python脚本将文字转换为图片的实例分享
2015/08/29 Python
Python中列表、字典、元组数据结构的简单学习笔记
2016/03/20 Python
Python第三方库xlrd/xlwt的安装与读写Excel表格
2017/01/21 Python
python记录程序运行时间的三种方法
2017/07/14 Python
Python Django的安装配置教程图文详解
2019/07/17 Python
Django后台管理系统的图文使用教学
2020/01/20 Python
css3实例教程 一款纯css3实现的发光屏幕旋转特效
2014/12/07 HTML / CSS
html5调用摄像头功能的实现代码
2018/05/07 HTML / CSS
Cotton On美国网站:澳洲时装连锁品牌
2016/10/25 全球购物
Yahoo的PHP面试题
2014/05/26 面试题
英语课前三分钟演讲稿(6篇)
2014/09/13 职场文书
承德避暑山庄导游词
2015/02/03 职场文书
标准演讲稿格式结尾应该怎么书写?
2019/07/17 职场文书
SQL Server内存机制浅探
2022/04/06 SQL Server