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,一经查实,立即删除!

相关文章

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 输入关键字&…

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

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

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

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

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

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

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

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

bat 连续读取两行_Redis底层数据结构解析(BAT大厂必问)

Redis是一个key-value存储系统&#xff0c;现在在各种系统中的使用越来越多&#xff0c;大部分情况下是因为其高性能的特性&#xff0c;被当做缓存使用。Redis由于其丰富的数据结构也可以被应用到其他场景。Redis是一个K-V的非关系型数据库&#xff08;NoSQL&#xff09;&#…

smart原则_为什么现在少有人用德鲁克的SMART原则做目标管理了?

互联网平台充斥了各类成功学文章&#xff0c;但大多数鸡汤文只谈坚持&#xff0c;不谈策略。王健林定下一个亿的小目标被网友编成了各种段子&#xff0c;却极少有人去探究他实现目标的过程&#xff0c;用的什么方法。从企业规模来看&#xff0c;我们没有理由说王健林定下的目标…

团队组成五个基本要素_【记录】综合分部宁波分队团队拓展活动

初冬&#xff0c;像一位美丽的、高贵的、矜持的公主&#xff0c;舞动着她那神奇的面纱&#xff0c;送来阵阵凛冽的寒风。今年宁波分队队伍逐渐壮大&#xff0c;从年初的70多人到目前120人&#xff0c;队伍中也迎来了许多00后的小伙伴们&#xff0c;为加强企业文化建设&#xff…

linux delete内存不下降_linux内存分配管理

linux内存分配管理一、前言作为从事与C/C程序开发人员&#xff0c;我们一直需要很好的管理内存&#xff0c;申请和释放&#xff1b;可能很多只知道使用malloc、new去申请&#xff0c;使用free、delete去释放&#xff0c;但是&#xff0c;去根究其内部的原理&#xff0c;可能就不…

android studio 2.3 instant run,android studio 2.3 instant run not working

可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效&#xff0c;请关闭广告屏蔽插件后再试):问题:I have updated android studio from 2.2 to 2.3,then I found Instant run not working.Error while executing: am startservice com.example.codingmaster.te…

和catch的区别_BIO、NIO、AIO 的区别是什么?

BIO、NIO、AIO 的区别是什么&#xff1f;同/异步、阻/非阻塞的区别是什么&#xff1f;文件读写最优雅的实现方式是什么&#xff1f;NIO 如何实现多路复用功能&#xff1f;带着以上这几个问题&#xff0c;跟着芒果一起进入IO的世界吧。在开始之前&#xff0c;我们先来思考一个问…

302状态码_HTTP协议详解(基础概念 方法 状态码 首部 连接 Cookie 新特性 安全)

一 、基础概念URIURI 包含 URL 和 URN。请求和响应报文1. 请求报文2. 响应报文二、HTTP 方法客户端发送的 请求报文 第一行为请求行&#xff0c;包含了方法字段。GET获取资源当前网络请求中&#xff0c;绝大部分使用的是 GET 方法。HEAD获取报文首部和 GET 方法类似&#xff0c…

flask get 参数_用它 5 分钟以后,我放弃用了四年的 Flask

“ 阅读本文大概需要 3 分钟。 ”有一个非常简单的需求&#xff1a;编写一个 HTTP 接口&#xff0c;使用 POST 方式发送一个 JSON 字符串&#xff0c;接口里面读取发送上来的参数&#xff0c;对其中某个参数进行处理&#xff0c;并返回。如果我们使用 Flask 来开发这个接口&…

android sse 人脸识别,基于Android Camera2之openCamera 流程

简介frameworks\base\core\java\android\hardware\camera2Camera2在Android 5.0上首次出现&#xff0c;主要重新定义了一套Camera 的使用接口API&#xff0c;设计思想出现了变化&#xff0c;具体的可自行搜索&#xff0c;此处主要介绍下Camera2的常见类以及使用流程。CameraCap…

vscode编辑python_VSCode+Python开发环境

准备开始转向用VSCode做开发&#xff0c;所以把一些常用的开发环境转移到VSCode上。 这次搭建的是Python3的开发环境。 其他相关博文&#xff1a; 一、测试环境 Windows 10 VSCode v1.11.1 Python v3.6.1 二、安装Visual Studio Code 三、安装Python这一步&#xff0c;记得…

html5 css3浏览器,五大主流浏览器CSS3和HTML5兼容性大比拼

五大主流浏览器CSS3和HTML5兼容性大比拼出处&#xff1a;快科技 2011-05-26 16:15:42 编辑&#xff1a;萧萧[爆料] 收藏文章各大主流浏览器对CSS3和HTML5的支持越来越完善&#xff0c;曾经让多少前端开发人员心碎的IE系也开始拥抱标准。就在前几天&#xff0c;W3C的HTML5社…

一个控制器怎么转发到另外一个控制器_楼宇自动化系统(BAS),DDC,一个最核心的控制器...

楼宇自动化系统(BAS)&#xff0c;一个熟悉又陌生的系统楼宇自控系统(BAS系统)设有一个中央监控中心&#xff0c;系统配置一个或多个网络控制器&#xff0c;由多条总线或计算机网络将各种功能的控制器与中央工作站相连&#xff0c;完成对空调、给排水、通风、电梯等子系统的监控…

html封装windows,windows 系统封装,打造一份属于自己的系统!

在电脑的使用过程中&#xff0c;由于我们每个人的使用习惯和使用方式不同&#xff0c;所以我们都会对Windows系统进行自己的设置&#xff0c;尤其是一些搞数码软件的&#xff0c;如果不小心系统坏了&#xff0c;重装系统后&#xff0c;还得一一去进行重新设置&#xff0c;非常麻…

python语言例子_【Python】SimPy的使用示例-Go语言中文社区

使用SimPY进行离散事件仿真 SimPY是一个Python下的第三方库&#xff0c;可以方便的进行离散事件的仿真。仿真速度比较快。下面记录一下我的一点心得&#xff0c;不保证完全正确&#xff0c;供参考。 安装 $ pip install -U simpy pycharm可以再File | Settings | Project: Simu…