ieee39节点系统介绍_Java秒杀系统实战系列-基于ZooKeeper的分布式锁优化秒杀逻辑...

本文是“Java秒杀系统实战系列文章”的第十六篇,本文我们将继续秒杀系统的优化之路,采用统一协调调度中心中间件ZooKeeper控制秒杀系统中高并发多线程对于共享资源~代码块的并发访问所出现的并发安全问题,即用ZooKeeper实现一种分布式锁!

ZooKeeper,看到其名字,不由得联想至 Zoo + Keeper,即动物园的看管所!这个寓意用以表达的是一种统一协调管理思想,动物园有很多动物,这些动物就类似于分布式系统架构时代所部署的不同系统服务节点,而这些动物~服务节点偶尔可能需要打交道,相互之间可能需要进行相应的问候,这个时候得需要有一个“看管者”,其职责除了需要管理动物园里的这些动物的行为之外(即这些系统服务的行为),还需要统一协调管理这些动物之间的“问候”、“打交道”(系统服务之间的调用)!

ZooKeeper对外会提供一个多层级的节点命名空间(节点称为ZNode),每个节点都用一个以斜杠(/)分隔的路径表示,而且每个节点都有父节点(根节点除外)。ZooKeeper的相关功能特性在实际使用过程中,其底层可能需要动态的添加、删减相应的节点,此时zk会提供一个Watcher监听器,用以监听那些动态新增、删减的节点,即ZooKeeper会在某些业务场景对一些节点使用上Watcher机制,监听相应的节点的动态。

04ebba714c5403301bd0effdc6b6b52f.png

我们即将要在下面介绍的“分布式锁”功能组件即为ZooKeeper提供给开发者的一大利器,其底层的实现原理正是基于Watcher机制 + 动态创建、删减临时顺序节点 所实现的,值得一提的是,一个ZNode节点将代表一个路径。

以下为ZooKeeper实现(获取)分布式锁的原理:

(1)当前线程在获取分布式锁的时候,会在ZNode节点(ZNode节点是Zookeeper的指定节点)下创建临时顺序节点,释放锁的时候将删除该临时节点。

(2)客户端/服务调用createNode方法在 ZNode节点 下创建临时顺序节点,然后调用getChildren(“ZNode”)来获取ZNode下面的所有子节点,注意此时不用设置任何Watcher。

(3)客户端/服务获取到所有的子节点path之后,如果发现自己创建的子节点序号最小,那么就认为该客户端获取到了锁,即当前线程获取到了分布式锁。

(4)如果发现自己创建的节点并非ZNode所有子节点中最小的,说明自己还没有获取到锁,此时客户端需要找到比自己小的那个节点,然后对其调用exist()方法,同时对其注册事件监听器。

之后,让这个被关注的节点删除(核心业务逻辑执行完,释放锁的时候,就是删除该节点),则客户端的Watcher会收到相应的通知,此时再次判断自己创建的节点是否是ZNode子节点中序号最小的,如果是则获取到了锁,如果不是则重复以上步骤继续获取到比自己小的一个节点并注册监听。

以上为ZooKeeper的基本介绍以及关于其底层实现分布式锁的原理的介绍,但是,Debug想说的是“理论再好,如果不会转化为实际的代码或者输出,那只能称之为泛泛而谈、吹牛逼” !

下面,我们将基于SpringBoot搭建的秒杀系统整合ZooKeeper,并基于ZooKeeper实现一种分布式锁,以此解决秒杀系统中高并发多线程并发产生的诸多问题。

(1)首先,当然是引入ZooKeeper的依赖啦,其中zk的版本在这里我们采用3.4.10,zk客户端操作实例curator的版本为2.12.0.

org.apache.zookeeper zookeeper 3.4.10org.slf4j slf4j-log4j12 log4j log4j org.apache.curator curator-framework 2.12.0org.apache.curator curator-recipes 2.12.0

紧接着,是在配置文件application.properties中加入ZooKeeper的配置,包括其服务所在的Host、端口Port、命名空间等等:

#zookeeperzk.host=127.0.0.1:2181zk.namespace=kill

(2)然后,跟Redis、Redisson一样,我们需要基于Spring Boot自定义注入ZooKeeper的相关操作Bean组件,即CuratorFramework实例的自定义配置,如下所示:

//ZooKeeper组件自定义配置@Configurationpublic class ZooKeeperConfig { @Autowired private Environment env; //自定义注入ZooKeeper客户端操作实例 @Bean public CuratorFramework curatorFramework(){ CuratorFramework curatorFramework=CuratorFrameworkFactory.builder() .connectString(env.getProperty("zk.host")) .namespace(env.getProperty("zk.namespace")) //重试策略 .retryPolicy(new RetryNTimes(5,1000)) .build(); curatorFramework.start(); return curatorFramework; }}

(3)接着,我们就可以拿来使用了,在KillService秒杀服务类中,我们创建了一个新的秒杀处理方法killItemV5,表示借助ZooKeeper中间件解决高并发多线程并发访问共享资源~共享代码块出现的并发安全问题!

@Autowiredprivate CuratorFramework curatorFramework;//TODO:路径就相当于一个ZNodeprivate static final String pathPrefix="/kill/zkLock/";//商品秒杀核心业务逻辑的处理-基于ZooKeeper的分布式锁@Overridepublic Boolean killItemV5(Integer killId, Integer userId) throws Exception { Boolean result=false; //定义获取分布式锁的操作组件实例 InterProcessMutex mutex=new InterProcessMutex(curatorFramework,pathPrefix+killId+userId+"-lock"); try { //尝试获取分布式锁 if (mutex.acquire(10L,TimeUnit.SECONDS)){ //TODO:核心业务逻辑 if (itemKillSuccessMapper.countByKillUserId(killId,userId) <= 0){ ItemKill itemKill=itemKillMapper.selectByIdV2(killId); if (itemKill!=null && 1==itemKill.getCanKill() && itemKill.getTotal()>0){ int res=itemKillMapper.updateKillItemV2(killId); if (res>0){ commonRecordKillSuccessInfo(itemKill,userId); result=true; } } }else{ throw new Exception("zookeeper-您已经抢购过该商品了!"); } } }catch (Exception e){ throw new Exception("还没到抢购日期、已过了抢购时间或已被抢购完毕!"); }finally { //释放分布式锁 if (mutex!=null){ mutex.release(); } } return result;}

从上述该源代码中可以看出其核心的处理逻辑在于“定义操作组件实例”、“获取锁”以及“释放锁”的实现上,如下所示:

//定义获取分布式锁的操作组件实例InterProcessMutex mutex=new InterProcessMutex(curatorFramework,pathPrefix+killId+userId+"-lock");//尝试获取分布式锁mutex.acquire(10L,TimeUnit.SECONDS)//释放锁mutex.release();

(4)至此,基于统一协调调度中心中间件ZooKeeper实现的分布式锁的代码我们已经实战完毕了,下面我们按照惯例,进入压测环节,数据用例以及压测的线程组的线程数我们仍旧跟以前一样,total=6本书,用户Id为10040~10049即10个用户,线程数为1w。

点击JMeter的启动按钮,即可发起秒级并发1w个线程的请求,稍等片刻(因为ZooKeeper需要不断的在当前设定的节点创建、删除临时节点,故而耗时还是比较长的),观察控制台的输出以及数据库表item_kill、item_kill_success表最终的数据记录结果,如下图所示:

a1ea88e6c1ac2335100d29d7e20aa860.png

对于这样的结果,可谓是皆大欢喜吧!至此,本文关于ZooKeeper的应用实战我们就介绍到这里了!

相关视频教程可私信咨询。

推荐阅读:

Java商城秒杀系统的设计与实战教程(SpringBoot版)

Java秒杀系统实战系列-构建SpringBoot多模块项目

Java秒杀系统实战系列-基于Redis的原子操作优化秒杀逻辑

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/502425.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

curl shell 失败_linux – curl命令不在bash中通过shell脚本执行

我正在学习shell脚本&#xff01;同样我尝试在ubuntu终端上使用curl下载facebook页面.t.sh内容vivi-Dell-7537(Desktop) $cat t.shcurlCmd"curl \"https://www.facebook.com/vivekkumar27june88\""echo $curlCmd($curlCmd) > ~/Desktop/fb.html运行脚本…

centos配置c语言环境变量,CentOS7设置环境变量

一、环境变量的概念1、环境变量的含义程序(操作系统命令和应用程序)的执行都需要运行环境&#xff0c;这个环境是由多个环境变量组成的。2、环境变量的分类1)按生效的范围分类。系统环境变量&#xff1a;公共的&#xff0c;对全部的用户都生效。用户环境变量&#xff1a;用户私…

python 3.7.732位安装步骤_Python3.7安装pyaudio教程解析

本人笔记本电脑安装的是 python3.7, 64位操作系统&#xff0c;基于x64的处理器 因为 pyaudio 暂时不支持 python3.7 和 3.8&#xff0c;所以若需要安装 pyaudio 需要下载 whl 文件后再离线进行安装。 首先&#xff1a;下载安装 pyaudio 的 whl 文件 然后按下 ctrlf 输入关键字&…

java语言程序设计是c语言吗,浅析C语言和Java语言的异同.pdf

新一代信息技 m0 l0、… … … …浅析C语言和Java语言的异同张亚荣(通辽职业学院信息技术系&#xff0c;内蒙古通辽 028000)【摘 要l文章根据本人多年对c语言和Java语言教学过程中遇到的一些实际问题&#xff0c;诸如Java语言是不是c语言发展和衍生的产物等。基于此&#xff0c…

python搜论文_python论文

浅谈我眼中的 python 吴凡 摘要&#xff1a; 作为一门非常有潜力的高级语言&#xff0c; python 正在编程上发挥着越来越大的作用。这学期&#xff0c;通 过对 python 基础知识的学习&#xff0c;对 python 有了一定的认识。同时和已经学习的高级语言 C 和 C 有了一定的对比&am…

图书管理系统c语言报告调试分析,图书管理系统C语言程序设计实验分析报告.doc...

图书管理系统C语言程序设计实验分析报告C语言程序设计实验报告系别专业班级姓名学号时间实验题目 图书信息管理系统一、实验目的(1)熟练掌握C语言的相关操作。(2)综合应用C语言的知识&#xff0c;独立完成一个完整的系统&#xff0c;提高编程能力&#xff0c;体会软件程序的开发…

python open写入_Python3 open() 函数详解 读取文件写入文件追加文件二进制文件

Python3 open() 函数详解 读取文件写入文件追加文件二进制文件 open()函数的主要作用是打开文件并返回相应文件对象&#xff0c;使用文件对象可以对当前文件进行读取、写入、追加等操作&#xff0c;默认情况下"r"模式&#xff0c;文件不存在的话会发生OSError错误的。…

python deepcopy报错_python 字典对象赋值之deepcopy遭遇的问题及解决过程(lxml惹的祸)...

今天在写一段代码的时候&#xff0c;需要对字典进行传值操作。一般情况下字典a 字典b&#xff0c;意味着是传引用&#xff0c;b发送改变的情况下a也会发生改变。我的字典如下a{testcase: {attributes: {classname: testdemo, circles: 2, casecode: case02, description: u/u6…

c语言printf函数很长时间,C语言学习之printf()函数特别注意事项

https://m.toutiao.com/is/eLAopLB/做为C语言程序的输出函数printf()在使用时除了其正常的使用之外&#xff0c;还有特别要注意的地方&#xff1a;1、在函数里面&#xff0c;基本上只有三种字符&#xff0c;一种为格式字符&#xff0c;最常见的有%d(十进制整数),%f(浮点数形式)…

python的三种结构_Python控制结构,python

比较运算符 布尔类型 布尔值有两个&#xff1a;True和False 例1&#xff1a; a True a 例2&#xff1a; 2 3 提示&#xff1a; 1.不要把赋值&#xff08;一个等号&#xff09;与比较&#xff08;两个等号&#xff09;混淆。 2.Python是区分大小写的&#xff0c;所以True与tru…

机器人 知乎碧桂园_万亿负债之下,碧桂园启动人事调整

原标题&#xff1a;万亿负债之下&#xff0c;碧桂园启动人事调整疫情之下&#xff0c;各行各业如履薄冰。作为资金密集型和人员密集型行业&#xff0c;房地产业头顶本就悬着一把「房主不炒」的达摩克里斯之剑&#xff0c;现在又面临销售阻遏&#xff0c;受到的冲击尤其大&#…

python转换函数使用_Python Socket模块中的IP转换函数

Python Socket模块中包含一些有用IP转换函数&#xff0c;说明如下&#xff1a; socket.ntohl(x) // 类似于C语言的ntohl(x) 把32位正整数从网络序转换成主机字节序。 socket.ntohs(x) // 类似于C语言的ntohs(x) 把16位正整数从网络序转换成主机字节序。 socket.htonl(x) // 类似…

嵌入式 c语言 面试题,嵌入式面试题-持续更新

1.用预处理指令#define声明一个常数&#xff0c;用以表示1年中有多少秒(忽略闰年问题)。#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL //最后的UL代表无符号整数。2.写一个“标准”宏MIN&#xff0c;这个宏输入两个参数并返回较小的一个。#define MIN(x, y) ((x) < …

一部分 数据 迁移_从虚机到容器,知名架构师告诉你如何平滑进行业务迁移

【小宅按】近期&#xff0c;短视频产品“秒拍”完成了一个“大动作”——将原来部署在虚拟机上的主体业务迁移到华为云&#xff0c;同时将公司的技术体系承载在下一代虚拟技术容器&#xff08;Docker&#xff09;上。而这一系列动作是在业务不下线&#xff0c;用户无感知的前提…

cuda 实现sift gpu_为Keras提供GPU加速

在刚入坑机器学习时&#xff0c;书上所使用的算法&#xff08;回归、决策树等&#xff09;及实例较为简单&#xff0c;一般CPU&#xff08;中央处理器&#xff09;的计算能力均能胜任&#xff0c;从而快速实现。但若使用keras&#xff08;一种基于深度学习框架的高级应用接口&a…

caged系统pdf_建筑行业单词中英文对照教材.pdf

智能建筑系统 BUILDING AUTOMATION & CONTROL SYSTEMS监视和警报 13850-detection & alarm公用建筑设备 public building equipment登记设备 registration equipment固体废物处理设备 solid waste handling equipment给水和水处理设备 WATER SUPPLY & TREATMENT EQ…

枚举算法称硬币C语言,【算法系列之枚举】称硬币

题目有12枚硬币。其中有11枚真币和1枚假币。假币和真 币重量不同&#xff0c;但不知道假币比真币轻还是重。现在&#xff0c; 用一架天平称了这些币三次&#xff0c;告诉你称的结果&#xff0c;请你 找出假币并且确定假币是轻是重(数据保证一定能找 出来)。输入第一行是测试数据…

此 sqltransaction 已完成;它再也无法使用_win10笔记本自带office报错无法激活的解决方法...

激活win10笔记本电脑自带office出错怎么办?不少笔记本电脑在出厂的时候就自带windows 10操作系统并且将系统部署完成后就有许多软件集成当中&#xff0c;一般按正常步骤进行激活即可正常使用&#xff0c;不过有用户遇到一个问题&#xff0c;在激活自带office时报错了&#xff…

js br不生效_前端标注工具-AILabel.js

# AILabel.js背景&#xff1a;在前端开发过程中难免遇到针对图片的缩放平移&#xff1b;以及在图片上进行矢量数据、文本、标注的展示&#xff1b;如果你有上面的任何需求&#xff0c;恭喜你&#xff0c;找到组织了....<br/>在此背景下&#xff0c;AILabel.js出生了### 相…

android中的后退功能,如何在Android应用中实现一个返回键功能

如何在Android应用中实现一个返回键功能发布时间&#xff1a;2020-11-23 16:28:56来源&#xff1a;亿速云阅读&#xff1a;89作者&#xff1a;Leah今天就跟大家聊聊有关如何在Android应用中实现一个返回键功能&#xff0c;可能很多人都不太了解&#xff0c;为了让大家更加了解&…