文章列表

python scrapy ModuleNotFoundError: No module named 'items'

作者:じ☆ve不哭

> python爬虫框架scrapy在pycharm中执行没有问题,但是部署服务器时提示:ModuleNotFoundError: No module named 'items'什么原因造成的呢? **1.爬虫名字和项目名字一样,导致导入模块时出错:改爬虫或者项目名称** **2.模块不存在:检查你的项目中的items,看看有没有出错** **3.模块没有保存:在编辑好items模块时,记得运行编译** **4.模块名字和引入的不一样:自行检查** **5.pycharm设置 mark directory as -> srouces root时应该从最外层的根路径下设置,这样导入应该是from 项目名.items import xxxItem** 经过以上的步骤这个问题应该就可以解决。如果你有其他的建议可以留言分享给大家

virtualenv --no-site-packages 提示无效怎么解决

作者:じ☆ve不哭

> virtualenv 执行是提示 --no-site-packages 怎么解决呢? ## 解决办法(Linux) ``` 1、输出环境变量 echo $VIRTUALENVWRAPPER_VIRTUALENV_ARGS 如果输出--no-site-packages就是这个变量的问题 vi /etc/profile (找到变量将值修改为空例如:) export VIRTUALENVWRAPPER_VIRTUALENV_ARGS= 保存 source /etc/profile ``` 如上操作即可解决

为了让你彻底弄懂 MySQL 事务日志,我通宵肝出了这份图解!

作者:微信小助手

<section style="display: none;" data-tools="新媒体管家" data-label="powered by xmt.cn" data-mpa-powered-by="yiban.io"> <br> </section> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;"> <p style="white-space: normal;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;font-size: 16px;background-color: rgb(255, 255, 255);text-align: center;"><span style="caret-color: rgb(62, 62, 62);color: rgb(178, 178, 178);letter-spacing: 1px;font-size: 14px;">点击上方“</span><span style="letter-spacing: 0.544px;caret-color: rgb(62, 62, 62);color: rgb(0, 122, 170);"><strong mpa-from-tpl="t"><span style="letter-spacing: 1px;font-size: 14px;">五分钟学算法</span></strong></span><span style="caret-color: rgb(62, 62, 62);color: rgb(178, 178, 178);letter-spacing: 1px;font-size: 14px;">”,选择“星标”公众号</span><span style="color: rgb(178, 178, 178);letter-spacing: 1px;font-size: 14px;"></span></p> <section style="white-space: normal;color: rgb(0, 0, 0);font-size: 16px;text-align: left;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);"> <section> <section> <section data-id="85660" data-custom="rgb(117, 117, 118)" data-color="rgb(117, 117, 118)"> <section> <section> <section> <section> <section> <section data-id="85660" data-custom="rgb(117, 117, 118)" data-color="rgb(117, 117, 118)"> <section> <p style="text-align: center;"><span style="letter-spacing: 0.544px;caret-color: rgb(62, 62, 62);font-size: 14px;color: rgb(178, 178, 178);">重磅干货,第一时间送达</span><img data-backh="34" data-backw="540" data-ratio="0.0625" data-s="300,640" src="/upload/8c292e55ba5a23cb6ebc11f2a2c4fece.jpg" data-type="jpeg" data-w="640" style="letter-spacing: 0.544px;text-align: left;caret-color: rgb(62, 62, 62);visibility: visible !important;width: 654px !important;" width="100%"></p> <p style="text-align: center;"><br></p> </section> </section> </section> </section> </section> </section> </section> </section> </section> </section> </section> <p style="text-align: center;"><img class="rich_pages" data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="233" data-ratio="0.425" data-s="300,640" src="/upload/518da9b7d830c0fbfa69e8ddb182398f.jpg" data-type="jpeg" data-w="1280" style="border-radius: 4px;width: 578px;height: 246px;"></p> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;"><br></span> <br> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">还记得刚上研究生的时候,导师常挂在嘴边的一句话,“科研的基础不过就是数据而已。”如今看来,无论是人文社科,还是自然科学,或许都可在一定程度上看作是数据的科学。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">倘若剥开研究领域的外衣,将人的操作抽象出来,那么科研的过程大概就是根据数据流动探索其中的未知信息吧。当然科学研究的范畴涵盖甚广,也不是一两句话能够拎得清的。不过从这个角度上的阐述,也只是为了引出数据的重要性。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">在当今社会,充斥着大量的数据。从众多APP上的账户资料到银行信用体系等个人档案,都离不开对大量数据的组织、存储和管理。而这,便是数据库存在的目的和价值。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">目前数据库的类型主要分为两种,一种是关系型数据库,另一种是非关系型数据库(NoSQL)。而我们今天的主角MySQL就是关系型数据库中的一种。</span> </section> <img data-ratio="0.8870431893687708" src="/upload/3793bd55a74d05f1d9245ecc95821b94.png" data-type="png" data-w="2408" style="display: block;margin-right: auto;margin-left: auto;"> <section style="margin: 10px 8px;text-align: center;"> <span style="font-size: 15px;">本文结构</span> </section> <section style="margin: 10px 8px;text-align: center;"> <span style="font-size: 15px;"><br></span> </section> <h2 data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;text-align: center;margin-left: 8px;margin-right: 8px;"><strong><span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;"><span style="color: rgb(255, 255, 255);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 20px;text-align: center;background-color: rgb(239, 112, 96);">&nbsp;1&nbsp;</span>&nbsp; </span><span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 20px;">关系型数据库与NoSQL</span></strong></h2> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">关系型数据库,顾名思义,是指存储的数据之间具有关系。这种所谓的关系通常用二维表格中的行列来表示,即一个二维表的逻辑结构能够反映表中数据的存储关系。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">概念总是拗口难懂的。那么简单来说,关系型数据库的存储就是按照表格进行的。数据的存储实际上就是对一个或者多个表格的存储。通过对这些表格进行分类、合并、连接或者选取等运算来实现对数据库的管理。常见的关系型数据库有MySQL、Oracle、DB2和SqlServer等。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">非关系型数据库(NoSQL)是相对于关系型数据库的一种泛指,它的特点是去掉了关系型数据库中的关系特性,从而可获得更好的扩展性。NoSQL并没有严格的存储方式,但采用不同的存储结构都是为了获得更高的性能和更高的并发。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">NoSQL根据存储方式可分为四大类,键值存储数据库、列存储数据库、文档型数据库和图形数据库。这四种数据的存储原理不尽相同,因而在应用场景上也有些许的差异。一般常用的有作为数据缓存的redis和分布式系统的HBase。目前常见的数据库排名可见网站:</span> </section> <blockquote data-tool="mdnice编辑器" style="font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);padding: 10px 10px 10px 20px;margin-bottom: 20px;margin-top: 20px;border-left-color: rgb(239, 112, 96);background: rgb(255, 249, 249);"> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> https://db-engines.com/en/ranking </section> </blockquote> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;"> <img src="/upload/e19ea5c106e51e30ac9b91185849cc17.png" data-cropx1="0" data-cropx2="1080" data-cropy1="0" data-cropy2="625.9515570934255" data-ratio="0.5796296296296296" src="https://mmbiz.qpic.cn/mmbiz_jpg/TdGLaSU675iaCHFO63Imian2ibWop8NxviauAY0Y3dS8ibvSEs06Gx6sLn9FMRlLalEXicZqfMVR8kS4Wz47UVUpIuqw/640?wx_fmt=jpeg" data-type="jpeg" data-w="1080" style="display: block;margin-right: auto;margin-left: auto;width: 578px;height: 335px;"> </figure> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;text-align: center;"> <span style="font-size: 15px;"><span style="font-size: 15px;text-align: center;">四种</span><span style="font-size: 15px;text-align: center;"></span>NoSQL的特点比较</span> </figure> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">关系型数据库与非关系型数据库本质上的区别就在于存储的数据是否具有一定的逻辑关系,由此产生的两类数据库看的性能和优劣势上也有一定的区别。二者对比可见下图。</span> </section> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;text-align: center;"> <img src="/upload/e867f7574c44a658da1ced63da337f14.png" data-cropx1="0" data-cropx2="1080" data-cropy1="0" data-cropy2="969.7577854671281" data-ratio="0.8981481481481481" src="https://mmbiz.qpic.cn/mmbiz_jpg/TdGLaSU675iaCHFO63Imian2ibWop8Nxviau7YoQcS3I0S1jtuUQVOgWJCd8tVY3cloSJVcfr6zO8xqsm2Ribj2zN5w/640?wx_fmt=jpeg" data-type="jpeg" data-w="1080" style="display: block;margin-right: auto;margin-left: auto;width: 578px;height: 519px;"> <span style="font-size: 15px;text-align: center;">关系型数据库与NoSQL的优缺点对比</span> <span style="font-size: 15px;text-align: center;"></span> </figure> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;text-align: center;"> <br> </figure> <section style="margin: 10px 8px;text-align: center;"> <span style="color: rgb(255, 255, 255);"><strong style="font-size: 18px;text-align: center;"><span style="color: rgb(255, 255, 255);background-color: rgb(255, 76, 0);"></span></strong></span> </section> <h2 data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;white-space: normal;line-height: 26px;text-align: center;margin-left: 8px;margin-right: 8px;"><strong><span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;"><span style="color: rgb(255, 255, 255);font-size: 20px;background-color: rgb(239, 112, 96);">&nbsp;2&nbsp;</span>&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 20px;">MySQL简介</span></strong></h2> <h4 data-tool="mdnice编辑器" style="margin: 30px 8px 15px;font-weight: bold;font-size: 18px;"><span style="border-bottom: 4px solid rgb(239, 112, 96);display: none;"></span><span style="border-bottom: 4px solid rgb(239, 112, 96);">介绍</span><span style="border-bottom: 4px solid rgb(239, 112, 96);display: none;"></span></h4> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">在关系型数据库中,MySQL可以说是其中的王者。它是目前最流行的数据库之一,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL数据库具有以下几个方面的优势:</span> </section> <blockquote data-tool="mdnice编辑器" style="font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);padding: 10px 10px 10px 20px;margin-bottom: 20px;margin-top: 20px;border-left-color: rgb(239, 112, 96);background: rgb(255, 249, 249);"> <ul style="margin: 8px;padding-left: 25px;color: black;" class="list-paddingleft-2"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;text-align: left;color: rgb(1, 1, 1);"> 体积小、速度快; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;text-align: left;color: rgb(1, 1, 1);"> 代码开源,采用了 GPL 协议,可以修改源码来开发自己的 MySQL 系统; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;text-align: left;color: rgb(1, 1, 1);"> 支持大型的数据库,可以处理拥有上千万条记录的大型数据库; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;text-align: left;color: rgb(1, 1, 1);"> 使用标准的 SQL 数据语言形式,并采用优化的 SQL 查询算法,有效地提高查询速度; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;text-align: left;color: rgb(1, 1, 1);"> 使用 C 和 C++ 编写,并使用多种编译器进行测试,保证源代码的可移植性; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;text-align: left;color: rgb(1, 1, 1);"> 可运行在多个系统上,并且支持多种语言; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;text-align: left;color: rgb(1, 1, 1);"> 核心程序采用完全的多线程编程,可以灵活地为用户提供服务,充分利用CPU资源。 </section></li> </ul> </blockquote> <h4 data-tool="mdnice编辑器" style="margin: 30px 8px 15px;font-weight: bold;font-size: 18px;"><span style="border-bottom: 4px solid rgb(239, 112, 96);display: none;"></span><span style="border-bottom: 4px solid rgb(239, 112, 96);">逻辑架构</span><span style="border-bottom: 4px solid rgb(239, 112, 96);display: none;"></span></h4> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">MySQL的逻辑架构可分为四层,包括连接层、服务层、引擎层和存储层,各层的接口交互及作用如下图所示。需要注意的是,由于本文将主要讲解事务的实现原理,因此下文针对的都是InnoDB引擎下的情况。</span> </section> <blockquote data-tool="mdnice编辑器" style="font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);padding: 10px 10px 10px 20px;margin-bottom: 20px;margin-top: 20px;border-left-color: rgb(239, 112, 96);background: rgb(255, 249, 249);"> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong>连接层:</strong> 负责处理客户端的连接以及权限的认证。 </section> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong>服务层:</strong> 定义有许多不同的模块,包括权限判断,SQL接口,SQL解析,SQL分析优化, 缓存查询的处理以及部分内置函数执行等。MySQL的查询语句在服务层内进行解析、优化、缓存以及内置函数的实现和存储。 </section> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong>引擎层:</strong> 负责MySQL中数据的存储和提取。MySQL中的服务器层不管理事务,事务是由存储引擎实现的。其中使用最为广泛的存储引擎为InnoDB,其它的引擎都不支持事务。 </section> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong>存储层:</strong> 负责将数据存储与设备的文件系统中。 </section> </blockquote> <section style="text-align: center;margin-left: 8px;margin-right: 8px;"> <img class="rich_pages" data-ratio="0.68359375" data-s="300,640" src="/upload/e825de18a5baee0766a2bc52e4116c43.png" data-type="png" data-w="1280" style=""> </section> <section style="text-align: center;margin-left: 8px;margin-right: 8px;"> <span style="font-size: 15px;text-align: center;">MySQL的逻辑架构</span> <span style="font-size: 15px;text-align: center;"></span> </section> <h2 data-tool="mdnice编辑器" style="text-align: center;margin-left: 8px;margin-right: 8px;"><br></h2> <section style="margin-left: 8px;margin-right: 8px;"> <br> </section> <h2 data-tool="mdnice编辑器" style="text-align: center;margin-left: 8px;margin-right: 8px;"><span style="font-size: 18px;"><strong><span style="font-size: 18px;background-color: rgb(255, 76, 0);color: rgb(255, 255, 255);"></span></strong></span></h2> <h2 data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;white-space: normal;line-height: 26px;text-align: center;margin-left: 8px;margin-right: 8px;"><strong><span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;"><span style="color: rgb(255, 255, 255);font-size: 20px;background-color: rgb(239, 112, 96);">&nbsp;3&nbsp;</span>&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 20px;">MySQL事务</span></strong></h2> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">事务是MySQL区别于NoSQL的重要特征,是保证关系型数据库数据一致性的关键技术。事务可看作是对数据库操作的基本执行单元,可能包含一个或者多个SQL语句。这些语句在执行时,要么都执行,要么都不执行。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">事务的执行主要包括两个操作,提交和回滚。</span> </section> <blockquote data-tool="mdnice编辑器" style="font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);padding: 10px 10px 10px 20px;margin-bottom: 20px;margin-top: 20px;border-left-color: rgb(239, 112, 96);background: rgb(255, 249, 249);"> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong>提交</strong>:commit,将事务执行结果写入数据库。 </section> </blockquote> <blockquote data-tool="mdnice编辑器" style="font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);padding: 10px 10px 10px 20px;margin-bottom: 20px;margin-top: 20px;border-left-color: rgb(239, 112, 96);background: rgb(255, 249, 249);"> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong>回滚</strong>:rollback,回滚所有已经执行的语句,返回修改之前的数据。 </section> </blockquote> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">MySQL事务包含四个特性,号称ACID四大天王。</span> </section> <blockquote data-tool="mdnice编辑器" style="font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);padding: 10px 10px 10px 20px;margin-bottom: 20px;margin-top: 20px;border-left-color: rgb(239, 112, 96);background: rgb(255, 249, 249);"> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong>原子性(Atomicity)</strong> :语句要么全执行,要么全不执行,是事务最核心的特性,事务本身就是以原子性来定义的;实现主要基于undo log日志实现的。 </section> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong>持久性(Durability</strong> &nbsp;:保证事务提交后不会因为宕机等原因导致数据丢失;实现主要基于redo log日志。 </section> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong>隔离性(Isolation)</strong> :保证事务执行尽可能不受其他事务影响;InnoDB默认的隔离级别是RR,RR的实现主要基于锁机制、数据的隐藏列、undo log和类next-key lock机制。 </section> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong>一致性(Consistency)</strong> :事务追求的最终目标,一致性的实现既需要数据库层面的保障,也需要应用层面的保障。 </section> </blockquote> <h4 data-tool="mdnice编辑器" style="margin: 30px 8px 15px;font-weight: bold;font-size: 18px;"><span style="border-bottom: 4px solid rgb(239, 112, 96);display: none;"></span><span style="border-bottom: 4px solid rgb(239, 112, 96);">原子性</span><span style="border-bottom: 4px solid rgb(239, 112, 96);display: none;"></span></h4> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">事务的原子性就如原子操作一般,表示事务不可再分,其中的操作要么都做,要么都不做;如果事务中一个SQL语句执行失败,则已执行的语句也必须回滚,数据库退回到事务前的状态。只有0和1,没有其它值。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">事务的原子性表明事务就是一个整体,当事务无法成功执行的时候,需要将事务中已经执行过的语句全部回滚,使得数据库回归到最初未开始事务的状态。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">事务的原子性就是通过undo log日志进行实现的。当事务需要进行回滚时,InnoDB引擎就会调用undo log日志进行SQL语句的撤销,实现数据的回滚。</span> </section> <h4 data-tool="mdnice编辑器" style="margin: 30px 8px 15px;font-weight: bold;font-size: 18px;"><span style="border-bottom: 4px solid rgb(239, 112, 96);display: none;"></span><span style="border-bottom: 4px solid rgb(239, 112, 96);">持久性</span><span style="border-bottom: 4px solid rgb(239, 112, 96);display: none;"></span></h4> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">事务的持久性是指当事务提交之后,数据库的改变就应该是永久性的,而不是暂时的。这也就是说,当事务提交之后,任何其它操作甚至是系统的宕机故障都不会对原来事务的执行结果产生影响。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">事务的持久性是通过InnoDB存储引擎中的redo log日志来实现的,具体实现思路见下文。</span> </section> <h4 data-tool="mdnice编辑器" style="margin: 30px 8px 15px;font-weight: bold;font-size: 18px;"><span style="border-bottom: 4px solid rgb(239, 112, 96);display: none;"></span><span style="border-bottom: 4px solid rgb(239, 112, 96);">隔离性</span><span style="border-bottom: 4px solid rgb(239, 112, 96);display: none;"></span></h4> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">原子性和持久性是单个事务本身层面的性质,而隔离性是指事务之间应该保持的关系。隔离性要求不同事务之间的影响是互不干扰的,一个事务的操作与其它事务是相互隔离的。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">由于事务可能并不只包含一条SQL语句,所以在事务的执行期间很有可能会有其它事务开始执行。因此多事务的并发性就要求事务之间的操作是相互隔离的。这一点跟多线程之间数据同步的概念有些类似。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong>锁机制</strong> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">事务之间的隔离,是通过锁机制实现的。当一个事务需要对数据库中的某行数据进行修改时,需要先给数据加锁;加了锁的数据,其它事务是不运行操作的,只能等待当前事务提交或回滚将锁释放。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">锁机制并不是一个陌生的概念,在许多场景中都会利用到不同实现的锁对数据进行保护和同步。而在MySQL中,根据不同的划分标准,还可将锁分为不同的种类。</span> </section> <blockquote data-tool="mdnice编辑器" style="font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);padding: 10px 10px 10px 20px;margin-bottom: 20px;margin-top: 20px;border-left-color: rgb(239, 112, 96);background: rgb(255, 249, 249);"> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong>按照粒度划分</strong>:行锁、表锁、页锁 </section> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong>按照使用方式划分</strong>:共享锁、排它锁 </section> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong>按照思想划分</strong>:悲观锁、乐观锁 </section> </blockquote> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">锁机制的知识点很多,由于篇幅不好全部展开讲。这里对按照粒度划分的锁进行简单介绍。</span> </section> <blockquote data-tool="mdnice编辑器" style="font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);padding: 10px 10px 10px 20px;margin-bottom: 20px;margin-top: 20px;border-left-color: rgb(239, 112, 96);background: rgb(255, 249, 249);"> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong>粒度</strong>:指数据仓库的数据单位中保存数据的细化或综合程度的级别。细化程度越高,粒度级就越小;相反,细化程度越低,粒度级就越大。 </section> </blockquote> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">MySQL按照锁的粒度划分可以分为行锁、表锁和页锁。</span> </section> <blockquote data-tool="mdnice编辑器" style="font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);padding: 10px 10px 10px 20px;margin-bottom: 20px;margin-top: 20px;border-left-color: rgb(239, 112, 96);background: rgb(255, 249, 249);"> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong>行锁</strong>:粒度最小的锁,表示只针对当前操作的行进行加锁; </section> </blockquote> <blockquote data-tool="mdnice编辑器" style="font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);padding: 10px 10px 10px 20px;margin-bottom: 20px;margin-top: 20px;border-left-color: rgb(239, 112, 96);background: rgb(255, 249, 249);"> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong>表锁</strong>:粒度最大的锁,表示当前的操作对整张表加锁; </section> </blockquote> <blockquote data-tool="mdnice编辑器" style="font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);padding: 10px 10px 10px 20px;margin-bottom: 20px;margin-top: 20px;border-left-color: rgb(239, 112, 96);background: rgb(255, 249, 249);"> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong>页锁</strong>:粒度介于行级锁和表级锁中间的一种锁,表示对页进行加锁。 </section> </blockquote> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;"> <img data-ratio="1.0284414106939703" src="/upload/9ec5070b3be44b1d362cd6cd804aeac3.png" data-type="png" data-w="1758" style="display: block;margin-right: auto;margin-left: auto;width: 244px;height: 251px;"> </figure> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;text-align: center;"> <span style="font-size: 15px;text-align: center;">数据库的粒度划分</span> <span style="font-size: 15px;text-align: center;"></span> </figure> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">这三种锁是在不同层次上对数据进行锁定,由于粒度的不同,其带来的好处和劣势也不一而同。</span> </section> <blockquote data-tool="mdnice编辑器" style="font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);padding: 10px 10px 10px 20px;margin-bottom: 20px;margin-top: 20px;border-left-color: rgb(239, 112, 96);background: rgb(255, 249, 249);"> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> 表锁在操作数据时会锁定整张表,因而并发性能较差; </section> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> 行锁则只锁定需要操作的数据,并发性能好。但是由于加锁本身需要消耗资源(获得锁、检查锁、释放锁等都需要消耗资源),因此在锁定数据较多情况下使用表锁可以节省大量资源。 </section> </blockquote> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">MySQL中不同的存储引擎能够支持的锁也是不一样的。MyIsam只支持表锁,而InnoDB同时支持表锁和行锁,且出于性能考虑,绝大多数情况下使用的都是行锁。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong><span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">并发读写问题</span></strong> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">在并发情况下,MySQL的同时读</span> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">写可能会导致三类问题,脏读、不可重复度和幻读。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">(1)<strong>脏读</strong>:当前事务中读到其他事务未提交的数据,也就是脏数据。</span> </section> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;"> <img data-ratio="0.4306254493170381" src="/upload/f32ae96c7e025411146afa6d5b9b0ec6.png" data-type="png" data-w="1391" style="display: block;margin-right: auto;margin-left: auto;"> </figure> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">以上图为例,事务A在读取文章的阅读量时,读取到了事务B为提交的数据。如果事务B最后没有顺利提交,导致事务回滚,那么实际上阅读量并没有修改成功,而事务A却是读到的修改后的值,显然不合情理。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">(2)<strong>不可重复读</strong>:在事务A中先后两次读取同一个数据,但是两次读取的结果不一样。脏读与不可重复读的区别在于:前者读到的是其他事务未提交的数据,后者读到的是其他事务已提交的数据。</span> </section> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;"> <img data-ratio="0.5427749820273184" src="/upload/7aea33e45ae2be022e52a7d0043ecdb3.png" data-type="png" data-w="1391" style="display: block;margin-right: auto;margin-left: auto;"> </figure> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">以上图为例,事务A在先后读取文章阅读量的数据时,结果却不一样。说明事务A在执行的过程中,阅读量的值被其它事务给修改了。这样使得数据的查询结果不再可靠,同样也不合实际。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">(3)<strong>幻读</strong>:在事务A中按照某个条件先后两次查询数据库,两次查询结果的行数不同,这种现象称为幻读。不可重复读与幻读的区别可以通俗的理解为:前者是数据变了,后者是数据的行数变了。</span> </section> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;"> <img data-ratio="0.5183321351545651" src="/upload/18357992a7610b1a712c68af6b26c152.png" data-type="png" data-w="1391" style="display: block;margin-right: auto;margin-left: auto;"> </figure> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">以上图为例,当对0&lt;阅读量&lt;100的文章进行查询时,先查到了一个结果,后来查询到了两个结果。这表明同一个事务的查询结果数不一,行数不一致。这样的问题使得在根据某些条件对数据筛选的时候,前后筛选结果不具有可靠性。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong><span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">隔离级别</span></strong> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">根据上面这三种问题,产生了四种隔离级别,表明数据库不同程度的隔离性质。</span> </section> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;"> <img data-ratio="0.437862950058072" src="/upload/277d33d4711aea34954cdc4deb7ea7f4.png" data-type="png" data-w="1722" style="display: block;margin-right: auto;margin-left: auto;"> </figure> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">在实际的数据库设计中,隔离级别越高,导致数据库的并发效率会越低;而隔离级别太低,又会导致数据库在读写过程中会遇到各种乱七八糟的问题。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">因此在大多数数据库系统中,默认的隔离级别时读已提交(如Oracle)或者可重复读RR(MySQL的InnoDB引擎)。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong><span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">MVCC</span></strong> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;"></span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">又是一个难嚼的大块头。MVCC就是用来实现上面的第三个隔离级别,可重复读RR。</span> </section> <blockquote data-tool="mdnice编辑器" style="font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);padding: 10px 10px 10px 20px;margin-bottom: 20px;margin-top: 20px;border-left-color: rgb(239, 112, 96);background: rgb(255, 249, 249);"> <section style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;color: black;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <strong>MVCC</strong>:Multi-Version Concurrency Control,即多版本的并发控制协议。 </section> </blockquote> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">MVCC的特点就是在同一时刻,不同事务可以读取到不同版本的数据,从而可以解决脏读和不可重复读的问题。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">MVCC实际上就是通过数据的隐藏列和回滚日志(undo log),实现多个版本数据的共存。这样的好处是,使用MVCC进行读数据的时候,不用加锁,从而避免了同时读写的冲突。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">在实现MVCC时,每一行的数据中会额外保存几个隐藏的列,比如当前行创建时的版本号和删除时间和指向undo log的回滚指针。这里的版本号并不是实际的时间值,而是系统版本号。每开始新的事务,系统版本号都会自动递增。事务开始时的系统版本号会作为事务的版本号,用来和查询每行记录的版本号进行比较。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">每个事务又有自己的版本号,这样事务内执行数据操作时,就通过版本号的比较来达到数据版本控制的目的。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">另外,InnoDB实现的隔离级别RR时可以避免幻读现象的,这是通过</span> <code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">next-key lock</code> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;">机制实现的。</span> </section> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-left: 8px;margin-right: 8px;"> <code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">next-key lock</code> <span style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Ro

python URL网址链接中的中文UrlEncode编码/UrlDecode解码

作者:じ☆ve不哭

> 做爬虫的时候时常会用到URL的编码,常常会有常用编码的转换例如:utf-8的UrlEncode编码/UrlDecode解码,gbk的UrlEncode编码/UrlDecode解码, gb2312的UrlEncode编码/UrlDecode解码那我们怎么转呢? ``` import urllib from urllib import parse def test(): str = '哔哩哔哩' str = str.encode(encoding='gb2312') print("中文转gb2312: ", str) str = urllib.parse.quote(str) print("UrlEncode编码: ", str) str = urllib.parse.unquote(str, encoding="gb2312") print("UrlDecode解码: ", str) if __name__ == '__main__': test() ``` **这样就可以做到UrlEncode编码/UrlDecode解码并且按照指定的文字编码(ANSI UNICODE UTF-8 GB2312 GBK DBCS UCS……)**

收集整理的较为经典的shell脚本合计(六)

作者:微信小助手

<section style="box-sizing: border-box;font-style: normal;text-align: justify;"> <section style="font-weight: 400;font-size: 16px;margin: 30px 0% 20px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;width: 100%;vertical-align: top;box-sizing: border-box;"> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;width: 100%;vertical-align: top;border-width: 3px;border-radius: 20px;border-style: solid;border-color: rgb(226, 241, 246);overflow: hidden;padding: 5px 10px;background-color: rgb(226, 241, 246);box-sizing: border-box;"> <section style="transform: translate3d(1px, 0px, 0px);box-sizing: border-box;" powered-by="xiumi.us"> <section style="text-align: center;font-size: 14px;color: rgb(149, 187, 202);box-sizing: border-box;"> <p style="margin: 0px;padding: 0px;box-sizing: border-box;">文章出自&nbsp; CSDN</p> </section> </section> </section> </section> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> </section> </section> </section> <section style="font-weight: 400;font-size: 16px;text-align: left;margin: 0px 0% -15px;transform: translate3d(20px, 0px, 0px);box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;width: 55px;height: 40px;vertical-align: top;overflow: hidden;box-sizing: border-box;"> <section style="text-align: center;margin: 0px 0%;box-sizing: border-box;" powered-by="xiumi.us"> <section style="max-width: 100%;vertical-align: middle;display: inline-block;line-height: 0;box-sizing: border-box;"> <img data-ratio="0.696" data-w="500" src="/upload/a040d38d88cdcfaed38ea2886a5b9df0.gif" style="vertical-align: middle;max-width: 100%;box-sizing: border-box;" data-type="gif"> </section> </section> </section> </section> <section style="font-weight: 400;font-size: 16px;box-sizing: border-box;" powered-by="xiumi.us"> <p style="text-align: center;white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><span style="text-shadow: rgb(195, 134, 234) 2px 0px 7px;box-sizing: border-box;"><strong style="box-sizing: border-box;">点击蓝字波哥的IT人生,关注我们<br style="box-sizing: border-box;"></strong></span></p> </section> <section style="font-weight: 400;font-size: 16px;text-align: right;margin: 0px 0% 10px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: middle;width: 40%;box-sizing: border-box;"> <section style="text-align: center;margin: 0px 0%;box-sizing: border-box;" powered-by="xiumi.us"> <section style="max-width: 100%;vertical-align: middle;display: inline-block;line-height: 0;width: 100%;box-sizing: border-box;"> <img data-ratio="0.2106667" data-w="750" src="/upload/9a990984a6b8f7f7b3c167d0a48d8599.gif" style="vertical-align: middle;max-width: 100%;width: 100%;box-sizing: border-box;" width="100%" data-type="gif"> </section> </section> </section> <section style="display: inline-block;vertical-align: middle;width: 25%;padding: 0px;box-sizing: border-box;"> <section style="margin: 0.5em 0px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="background-color: rgb(29, 29, 29);height: 1px;box-sizing: border-box;"> <br> </section> </section> </section> </section> <section powered-by="xiumi.us"> <p><br></p> <p><br></p> <p>50、删除某个目录下大小为 0 的文件</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="bash"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#!/bin/bash</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 删除某个目录下大小为 0 的文件</span></span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">#/var/www/html 为测试目录,脚本会清空该目录下所有 0 字节的文件</span></span></code><code><span class="code-snippet_outer">dir=<span class="code-snippet__string">"/var/www/html"</span></span></code><code><span class="code-snippet_outer">find <span class="code-snippet__variable">$dir</span> -<span class="code-snippet__built_in">type</span> f -size 0 -<span class="code-snippet__built_in">exec</span> rm -rf {} \;</span></code></pre> </section> <p>51、查找 Linux 系统中的僵尸进程</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="bash"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#!/bin/bash</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 查找 Linux 系统中的僵尸进程</span></span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># awk 判断 ps 命令输出的第 8 列为 Z 是,显示该进程的 PID 和进程命令</span></span></code><code><span class="code-snippet_outer">ps aux | awk <span class="code-snippet__string">'{if($8 == "Z"){print $2,$11}}'</span></span></code></pre> </section> <p>52、提示用户输入年份后判断该年是否为闰年</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="bash"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#!/bin/bash</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 提示用户输入年份后判断该年是否为闰年</span></span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 能被4整除并且并不能被100整除的年份是闰年</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 能被400整除的年份也是闰年</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">read</span> -p <span class="code-snippet__string">"请输入一个年份:"</span> year</span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> [ <span class="code-snippet__string">"<span class="code-snippet__variable">$year</span>"</span> = <span class="code-snippet__string">""</span> ];<span class="code-snippet__keyword">then</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__built_in">echo</span> <span class="code-snippet__string">"没有输入年份"</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__built_in">exit</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">fi</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">#使用正则测试变量 year 中是否包含大小写字母</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> [[ <span class="code-snippet__string">"<span class="code-snippet__variable">$year</span>"</span> =~ [a‐Z] ]];<span class="code-snippet__keyword">then</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__built_in">echo</span> <span class="code-snippet__string">"你输入的不是数字"</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__built_in">exit</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">fi</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 判断是否为闰年</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> [ $[year % 4] -eq 0 ] &amp;&amp; [ $[year % 100] -ne 0 ];<span class="code-snippet__keyword">then</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__built_in">echo</span> <span class="code-snippet__string">"<span class="code-snippet__variable">$year</span>年是闰年"</span> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">elif</span> [ $[year % 400] -eq 0 ];<span class="code-snippet__keyword">then</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__built_in">echo</span> <span class="code-snippet__string">"<span class="code-snippet__variable">$year</span>年是闰年"</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">else</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__built_in">echo</span> <span class="code-snippet__string">"<span class="code-snippet__variable">$year</span>年不是闰年"</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">fi</span></span></code></pre> </section> <p>53、生成随机密码(urandom 版本)</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="bash"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#!/bin/bash</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 生成随机密码(urandom 版本) </span></span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># /dev/urandom 文件是 Linux 内置的随机设备文件</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># cat /dev/urandom 可以看看里面的内容,ctrl+c 退出查看</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 查看该文件内容后,发现内容有些太随机,包括很多特殊符号,我们需要的密码不希望使用这些符号</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># tr ‐dc '_A‐Za‐z0‐9' &lt; /dev/urandom</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 该命令可以将随机文件中其他的字符删除,仅保留大小写字母,数字,下划线,但是内容还是太多</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 我们可以继续将优化好的内容通过管道传递给 head 命令,在大量数据中仅显示头 10 个字节</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 注意 A 前面有个下划线</span></span></code><code><span class="code-snippet_outer">tr -dc <span class="code-snippet__string">'_A‐Za‐z0‐9'</span> &lt;/dev/urandom | head -c 10</span></code></pre> </section> <p>54、生成随机密码(字串截取版本)</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="bash"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#!/bin/bash</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 生成随机密码(字串截取版本) </span></span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 设置变量 key,存储密码的所有可能性(密码库),如果还需要其他字符请自行添加其他密码字符</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 使用$#统计密码库的长度</span></span></code><code><span class="code-snippet_outer">key=<span class="code-snippet__string">"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"</span></span></code><code><span class="code-snippet_outer">num=<span class="code-snippet__variable">${#key}</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 设置初始密码为空</span></span></code><code><span class="code-snippet_outer">pass=<span class="code-snippet__string">''</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 循环 8 次,生成随机密码</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 每次都是随机数对密码库的长度取余,确保提取的密码字符不超过密码库的长度</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 每次循环提取一位随机密码,并将该随机密码追加到 pass 变量的最后</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">for</span> i <span class="code-snippet__keyword">in</span> {1..8}</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">do</span> </span></code><code><span class="code-snippet_outer"> index=$[RANDOM%num]</span></code><code><span class="code-snippet_outer"> pass=<span class="code-snippet__variable">$pass</span><span class="code-snippet__variable">${key:$index:1}</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">done</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">echo</span> <span class="code-snippet__variable">$pass</span></span></code></pre> </section> <p>55、生成随机密码(UUID 版本,16 进制密码)</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="bash"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#!/bin/bash</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 生成随机密码(UUID 版本,16 进制密码) </span></span></code><code><span class="code-snippet_outer">uuidgen</span></code></pre> </section> <p>56、生成随机密码(进程 ID 版本,数字密码)</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="bash"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#!/bin/bash</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 生成随机密码(进程 ID 版本,数字密码)</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">echo</span> $$</span></code></pre> </section> <p>57、测试用户名与密码是否正确</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="bash"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#!/bin/bash</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 测试用户名与密码是否正确</span></span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment">#用户名为 tom 并且密码为 123456,则提示登录成功,否则提示登录失败</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">read</span> -p <span class="code-snippet__string">"请输入用户名:"</span> user</span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">read</span> -p <span class="code-snippet__string">"请输入密码:"</span> pass</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> [ <span class="code-snippet__string">"<span class="code-snippet__variable">$user</span>"</span> == <span class="code-snippet__string">'tom'</span> -a <span class="code-snippet__string">"<span class="code-snippet__variable">$pass</span>"</span> == <span class="code-snippet__string">'123456'</span> ];<span class="code-snippet__keyword">then</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__built_in">echo</span> <span class="code-snippet__string">"Login successful"</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">else</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__built_in">echo</span> <span class="code-snippet__string">"Login Failed"</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">fi</span></span></code></pre> </section> <p>58、循环测试用户名与密码是否正确</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="bash"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#!/bin/bash</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 循环测试用户名与密码是否正确 </span></span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 循环测试用户的账户名和密码,最大测试 3 次,输入正确提示登录成功,否则提示登录失败</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 用户名为 tom 并且密码为 123456 </span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">for</span> i <span class="code-snippet__keyword">in</span> {1..3}</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">do</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__built_in">read</span> -p <span class="code-snippet__string">"请输入用户名:"</span> user</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__built_in">read</span> -p <span class="code-snippet__string">"请输入密码:"</span> pass</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">if</span> [ <span class="code-snippet__string">"<span class="code-snippet__variable">$user</span>"</span> == <span class="code-snippet__string">'tom'</span> -a <span class="code-snippet__string">"<span class="code-snippet__variable">$pass</span>"</span> == <span class="code-snippet__string">'123456'</span> ];<span class="code-snippet__keyword">then</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__built_in">echo</span> <span class="code-snippet__string">"Login successful"</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__built_in">exit</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">fi</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">done</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">echo</span> <span class="code-snippet__string">"Login Failed"</span></span></code></pre> </section> <p>59、Shell 脚本的 fork 炸弹</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="bash"><code><span class="code-snippet_outer"><span class="code-snippet__meta">#!/bin/bash</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># Shell 脚本的 fork 炸弹 </span></span></code><code><span class="code-snippet_outer"> </span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 快速消耗计算机资源,致使计算机死机</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__comment"># 定义函数名为.(点), 函数中递归调用自己并放入后台执行</span></span></code><code><span class="code-snippet_outer">.() { .|.&amp; };.</span></code></pre> </section> <p><br></p> <strong style="font-size: 17px;text-align: justify;color: rgb(51, 51, 51);max-width: 100%;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;">关注波哥,分享最有用的东西!</strong> <p style="font-weight: 400;"><span style="font-size: 17px;"><strong style="max-width: 100%;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;">江湖规矩:如文章对您有帮助,请帮波哥转发分享、点赞哦!</strong></span><br></p> </section> <section style="font-weight: 400;font-size: 16px;text-align: center;margin: 10px 0% 0px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;width: 250px;height: 95px;vertical-align: top;overflow: hidden;background-position: 50% 50%;background-repeat: no-repeat;background-size: contain;background-attachment: scroll;line-height: 1.6;background-image: url(&quot;https://mmbiz.qpic.cn/mmbiz_png/SRBEicJEW1Q08QPtycF0aCIOhuiceSjWXCWDsK48icPCibjkZicF9GsnSiczSVQpKeOpMHzkBibaoibNTkhrOy8JcSAPZw/640?wx_fmt=png&quot;);box-sizing: border-box;"> <section style="margin: 15px 0% 0px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="font-size: 14px;line-height: 1.5;box-sizing: border-box;"> <p style="margin: 0px;padding: 0px;box-sizing: border-box;">扫码关注<br></p> <p style="margin: 0px;padding: 0px;box-sizing: border-box;">绝对干货的公众号</p> </section> </section> </section> <br> </section> <section style="font-weight: 400;font-size: 16px;text-align: center;margin: 10px 0%;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: middle;width: 8%;box-sizing: border-box;"> <section style="margin: 0px 0%;box-sizing: border-box;" powered-by="xiumi.us"> <section style="max-width: 100%;vertical-align: middle;display: inline-block;line-height: 0;box-sizing: border-box;"> <img data-ratio="0.7434944" data-w="269" src="/upload/e6cbcf3697ad6e50610fecf01ccf25e3.gif" style="vertical-align: middle;max-width: 100%;box-sizing: border-box;" data-type="gif"> </section> </section> </section> <section style="display: inline-block;vertical-align: middle;width: 35%;box-sizing: border-box;"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="max-width: 100%;vertical-align: middle;display: inline-block;line-height: 0;box-sizing: border-box;"> <img data-ratio="1" data-w="344" src="/upload/fec8378b8286f808184c5e6d215ff424.jpg" style="vertical-align: middle;max-width: 100%;box-sizing: border-box;" data-type="jpeg"> </section> </section> </section> <section style="display: inline-block;vertical-align: middle;width: 8%;box-sizing: border-box;"> <section style="margin: 0px 0%;box-sizing: border-box;" powered-by="xiumi.us"> <section style="max-width: 100%;vertical-align: middle;display: inline-block;line-height: 0;box-sizing: border-box;"> <img data-ratio="0.7434944" data-w="269" src="/upload/f82ac25cbcf86584002fe49c162dafe4.gif" style="vertical-align: middle;max-width: 100%;box-sizing: border-box;" data-type="gif"> </section> </section> </section> </section> <section style="font-weight: 400;font-size: 16px;color: rgb(227, 46, 46);font-family: PingFangTC-ultralight;box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><br></p> </section> <section powered-by="xiumi.us" style="font-weight: 400;font-size: 16px;max-width: 100%;box-sizing: border-box;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(227, 46, 46);font-family: PingFangTC-ultralight;overflow-wrap: break-word !important;"> <p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;">推荐阅读</p> </section> <section powered-by="xiumi.us" style="font-weight: 400;font-size: 16px;max-width: 100%;box-sizing: border-box;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;"> <a title="https://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247484733&amp;idx=1&amp;sn=8a5fcad29d0fea680f8ba93fea44c0da&amp;chksm=fe7b0a01c90c8317e174ca316b1c15dd11bdfe41f1c70b3331576683ca87a0d2e8de267b99ad&amp;token=1047100134&amp;lang=zh_CN&amp;scene=21#wechat_redirect" formlinkparm="&quot;https://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247484733&amp;idx=1&amp;sn=8a5fcad29d0fea680f8ba93fea44c0da&amp;chksm=fe7b0a01c90c8317e174ca316b1c15dd11bdfe41f1c70b3331576683ca87a0d2e8de267b99ad&amp;token=1047100134&amp;lang=zh_CN&amp;scene=21#wechat_redirect&quot;" href="https://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247484733&amp;idx=1&amp;sn=8a5fcad29d0fea680f8ba93fea44c0da&amp;chksm=fe7b0a01c90c8317e174ca316b1c15dd11bdfe41f1c70b3331576683ca87a0d2e8de267b99ad&amp;token=1047100134&amp;lang=zh_CN&amp;scene=21#wechat_redirect" target="_blank" rel="noopener noreferrer" data-linktype="2" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box;font-size: 12px;overflow-wrap: break-word !important;"> <p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"></p> </section></a> </section> <section powered-by="xiumi.us" style="font-weight: 400;font-size: 12px;max-width: 100%;box-sizing: border-box;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;"> <p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><br></p> </section> <section powered-by="xiumi.us" style="font-weight: 400;font-size: 12px;white-space: normal;box-sizing: border-box;"> <p style="box-sizing: border-box;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247484673&amp;idx=1&amp;sn=f1c6fd7c00049734ed97121b5c401c6a&amp;chksm=fe7b0a3dc90c832b226d1df991f413a4dfaebce8c4be4549ebd777a688e08f61f651b1bcd337&amp;scene=21#wechat_redirect" textvalue="实战项目--kkitDeploy(客户端版)(强推)" data-itemshowtype="0" tab="innerlink" data-linktype="2">实战项目--kkitDeploy(客户端版)<span style="font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);">(强推<span style="letter-spacing: 0.544px;">,已开源</span>)</span></a></p> <p style="box-sizing: border-box;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247485054&amp;idx=1&amp;sn=76b2afbaa98227a0efb06e1c5e53be17&amp;chksm=fe7b0942c90c8054172c8ca3020ddeb28d32cee3d3807efc6e7c9b063d128ee31dcdc831f457&amp;scene=21#wechat_redirect" textvalue="实战项目--kkitDeploy(PaaS版)(强推)" data-itemshowtype="0" tab="innerlink" data-linktype="2"><span style="font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);">实战项目--kkitDeploy(PaaS版)<span style="letter-spacing: 0.544px;">(强推)</span></span></a></p> <p style="box-sizing: border-box;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247484871&amp;idx=1&amp;sn=eea93b8ec270325f961e41038eade6d4&amp;chksm=fe7b0afbc90c83ed0251453b69c1ac0e48db7444dd27caf8d8830b03235190cb7802058c64b6&amp;scene=21#wechat_redirect" textvalue="实战项目--kkit3.0功能介绍(强推)" data-itemshowtype="0" tab="innerlink" data-linktype="2"><span style="font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);">实战项目--kkit3.0<span style="letter-spacing: 0.544px;">功能介绍(强推)</span></span></a></p> <p style="box-sizing: border-box;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247483880&amp;idx=1&amp;sn=5a38522f8639330a62fd8bd1fe032972&amp;chksm=fe7b0ed4c90c87c26e4444cf21254dc613258082b28b4a6707a041edadb982ab0d13b994749a&amp;scene=21#wechat_redirect" textvalue="实战项目--kkit1.0功能介绍(强推,已开源)" data-itemshowtype="0" tab="innerlink" data-linktype="2"><span style="font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;background-color: rgb(255, 255, 255);letter-spacing: 0.544px;">实战项目--kkit1.0<span style="letter-spacing: 0.544px;">功能介绍(强推,已开源)</span></span></a></p> </section> <section powered-by="xiumi.us" style="font-weight: 400;font-size: 16px;white-space: normal;max-width: 100%;box-sizing: border-box;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box;font-size: 12px;overflow-wrap: break-word !important;"> <section powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box;letter-spacing: 0.544px;font-size: 16px;overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box;font-size: 12px;overflow-wrap: break-word !important;"> <p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><a href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247484768&amp;idx=1&amp;sn=4016a88bc54e9fe67b7b6d76fa3cedb4&amp;chksm=fe7b0a5cc90c834ae4e95f951324ffe2a9991b502da194c507c6d02b7b277403f00fcc123940&amp;scene=21#wechat_redirect" target="_blank" data-itemshowtype="0" data-linktype="2" hasload="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">面试题之---网络安全(2019年10月更新)</a></p> </section> </section> <section powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box;letter-spacing: 0.544px;font-size: 16px;overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box;font-size: 12px;overflow-wrap: break-word !important;"> <p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><a href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247484733&amp;idx=1&amp;sn=8a5fcad29d0fea680f8ba93fea44c0da&amp;chksm=fe7b0a01c90c8317e174ca316b1c15dd11bdfe41f1c70b3331576683ca87a0d2e8de267b99ad&amp;scene=21#wechat_redirect" target="_blank" data-itemshowtype="0" data-linktype="2" hasload="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">面试题之---k8s(2019年10月更新)</a></p> </section> </section> <section powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box;letter-spacing: 0.544px;font-size: 16px;overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box;font-size: 12px;overflow-wrap: break-word !important;"> <p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><a href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247484360&amp;idx=1&amp;sn=b0f6bdca5a3f4f4ac3c53c9f1ef9cbc9&amp;chksm=fe7b0cf4c90c85e2ee1afb0571603426ab172c5c2e1d85d4763b086a562f5673973d4230e17a&amp;scene=21#wechat_redirect" target="_blank" data-itemshowtype="0" data-linktype="2" hasload="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">面试题之---运维工程师经典面试汇总(一)</a></p> <p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><a href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247484747&amp;idx=1&amp;sn=b49dfe531c0c1331200a7e4947f65976&amp;chksm=fe7b0a77c90c8361f2ac4f3784681c7580c3699bf0f49d930b56999a2bd8e3e62fa3e6c9b521&amp;scene=21#wechat_redirect" target="_blank" data-itemshowtype="0" data-linktype="2" hasload="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">经历贴之---外包接活却坐牢456天完整记录(强推)</a></p> </section> </section> </section> </section> <section powered-by="xiumi.us" style="font-weight: 400;font-size: 16px;white-space: normal;max-width: 100%;box-sizing: border-box;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box;font-size: 12px;overflow-wrap: break-word !important;"> <p><a href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247484455&amp;idx=1&amp;sn=da41f73724909d3051343133cd53db74&amp;chksm=fe7b0b1bc90c820d954f649d76be230f651d62431858eb06bae8f5deaa36e66339f515116373&amp;scene=21#wechat_redirect" target="_blank" data-itemshowtype="0" data-linktype="2">脚本之---短信轰炸机</a></p> <p><a href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247484740&amp;idx=1&amp;sn=0683fbf63643218045c1b8cd522137ec&amp;chksm=fe7b0a78c90c836e85c254cce4b8c6897579fd4f6a1386b59084b6fe4cfdd3a72bbcbfbce96f&amp;scene=21#wechat_redirect" target="_blank" data-itemshowtype="0" data-linktype="2" style="font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;">脚本之---QQ微信轰炸机</a></p> <p><a href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247484909&amp;idx=1&amp;sn=27ab3125be7e9fd31e93fa1cb30bd3ae&amp;chksm=fe7b0ad1c90c83c7158a5679dec8d987a1f05f933efd4073d15ef83a98e897666ed88c235e2f&amp;scene=21#wechat_redirect" target="_blank" data-itemshowtype="0" data-linktype="2">脚本之---linux流量监控利器</a><br></p> <p><a href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247484957&amp;idx=1&amp;sn=ad4f9320dfd49a0c7a54042a20bb66c0&amp;chksm=fe7b0921c90c8037a273419352a5677461e9895ca945bd6e33fae2fc401443c6c7a34ef355d9&amp;scene=21#wechat_redirect" target="_blank" data-itemshowtype="0" data-linktype="2">脚本之---linux系统巡检脚本合集</a></p> <p><a href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247485039&amp;idx=1&amp;sn=ddd14e33325dfd99ac61ee83a4fc198c&amp;chksm=fe7b0953c90c8045e6de3e39cc83b53e067d1a19a051dd17129e8ec2386b36adc9c4d6d1589d&amp;scene=21#wechat_redirect" target="_blank" data-itemshowtype="0" data-linktype="2">脚本之---linux批量用户管理脚本</a></p> <p><a href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247485046&amp;idx=1&amp;sn=ee3e7a258eafcce88aa65e3daa3fd7be&amp;chksm=fe7b094ac90c805c6ed4e8eb16a698fee1e1b467e948b0e86288aa39cbfebd48ee5e383594c1&amp;scene=21#wechat_redirect" target="_blank" data-itemshowtype="0" data-linktype="2">脚本之---根据PID查看相关信息</a></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247485065&amp;idx=1&amp;sn=8913154de8cb68c4679d5a40957eaf18&amp;chksm=fe7b09b5c90c80a323324d176c0be3a3370f1ee3fc9d05625937b7d8c0df206c2e23b6c4773a&amp;scene=21#wechat_redirect" textvalue="脚本之---一键完成系统安全加固" data-itemshowtype="0" tab="innerlink" data-linktype="2">脚本之---一键完成系统安全加固</a></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247485059&amp;idx=1&amp;sn=f4671cd621367c9faf5d697b181e351a&amp;chksm=fe7b09bfc90c80a9d89b23553d1366d17686dd5e3542a17df738d9ead2274fb104943237bc5b&amp;scene=21#wechat_redirect" textvalue="脚本之---检查系统用户" data-itemshowtype="0" tab="innerlink" data-linktype="2">脚本之---检查系统用户</a></p> <p><a href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247485014&amp;idx=1&amp;sn=a633abf6ec6137240528957a16de2f33&amp;chksm=fe7b096ac90c807c09b7881315263c7d6cf87f0fa038d4159b00c2518e5bce619fe2bf68faea&amp;scene=21#wechat_redirect" target="_blank" data-itemshowtype="0" data-linktype="2">脚本之---一键同步脚本文件夹</a></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247485111&amp;idx=1&amp;sn=6332d3366f992980cd16862e9974b3c0&amp;chksm=fe7b098bc90c809d65219f1ffe51a03c68c76615bbef5beed46ec59bbea805e1e5d1eb8d8409&amp;scene=21#wechat_redirect" textvalue="脚本之---一键升/降级k8s集群脚本" data-itemshowtype="0" tab="innerlink" data-linktype="2">脚本之---一键升/降级k8s集群脚本</a></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247485122&amp;idx=1&amp;sn=d88e6ae5a5327b783c9c7e26fe4615ac&amp;chksm=fe7b09fec90c80e8c61c6e76b6ac514457e9872871a7bb0b6f285297b676307b99bde99278bb&amp;scene=21#wechat_redirect" textvalue="脚本之---一键升新增k8s集群node节点脚本" data-itemshowtype="0" tab="innerlink" data-linktype="2">脚本之---一键升新增k8s集群node节点脚本</a></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247485128&amp;idx=1&amp;sn=3adf091282012695ac2b7d6aadfe00c3&amp;chksm=fe7b09f4c90c80e287710850a2d4912cdea3484537b511c1451a30cd5767d1e7b1af90bbd660&amp;scene=21#wechat_redirect" textvalue="脚本之---k8s一键部署脚本(多版本通用版)" data-itemshowtype="0" tab="innerlink" data-linktype="2">脚本之---k8s一键部署脚本(多版本通用版)(强推)</a></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247485159&amp;idx=1&amp;sn=a0516b2fb0197e8bd603cbb225d96cf1&amp;chksm=fe7b09dbc90c80cd9fcebdf2285b48d50fd6bdda812565769b413da6b806411e5d634c4ba119&amp;scene=21#wechat_redirect" textvalue="脚本之---一键部署ceph(luminous)集群脚本" data-itemshowtype="0" tab="innerlink" data-linktype="2">脚本之---一键部署ceph(luminous)集群脚本</a></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247485197&amp;idx=1&amp;sn=5225f0b73fd496332db24f5cded6c87f&amp;chksm=fe7b0831c90c8127d737569822b00319193fb733a452f65c1e5eb936bc08aa914dcdf584850d&amp;scene=21#wechat_redirect" textvalue="脚本之---一键部署openvpn脚本" data-itemshowtype="0" tab="innerlink" data-linktype="2"><span style="letter-spacing: 0.544px;">脚本之---一键部署openvpn脚本</span></a><br></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247485203&amp;idx=1&amp;sn=7a4d5359527a6b8be6e7840e2db7fe25&amp;chksm=fe7b082fc90c813968dd6c244bb86b72deb8d68f81b02b7578dfe98db5deb5517ff7d755c747&amp;scene=21#wechat_redirect" textvalue="脚本之---一键(单双向)互信初始化服务器脚本" data-itemshowtype="0" tab="innerlink" data-linktype="2"><span style="font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 12px;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);">脚本之---一键(单双向)互信初始化服务器脚本</span></a></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247485388&amp;idx=1&amp;sn=d12267364d1066de084b3a02e55da1f0&amp;chksm=fe7b08f0c90c81e6044cea65f30026207dd4bf95098cdb01caf77f371038da8bdcc876b39ce5&amp;scene=21#wechat_redirect" textvalue="脚本之---一键初始化调优服务器脚本" data-itemshowtype="0" tab="innerlink" data-linktype="2">脚本之---一键初始化调优服务器脚本</a></p> <p><a href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247484965&amp;idx=1&amp;sn=50455d6e48c8e58f98a1b2b9ea3c0ae1&amp;chksm=fe7b0919c90c800f7a49d154072edc20a5cee3aca7dbd4e1e292b35664417d0acabfab7e58ff&amp;scene=21#wechat_redirect" target="_blank" data-itemshowtype="0" data-linktype="2">脚本之---zabbixAgent一键部署脚本(windos/linux)</a></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247485248&amp;idx=1&amp;sn=1134c6914570f1b5ad657cb0864d14d1&amp;chksm=fe7b087cc90c816a7b172c552061370bc6db54679af785dbc899580a66d1e4b227c783b66409&amp;scene=21#wechat_redirect" textvalue="ansible---一键搭建redis5.0.5集群" data-itemshowtype="0" tab="innerlink" data-linktype="2">ansible---一键搭建redis5.0.5集群</a></p> <p><a href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247483959&amp;idx=1&amp;sn=f1c132a3f3ef3c2cf53166d92bbb1c81&amp;chksm=fe7b0d0bc90c841d865c6ada6ad1b1747636b2ca719906ce5faf36a4775b595fb83cdcbd7988&amp;scene=21#wechat_redirect" target="_blank" data-itemshowtype="0" data-linktype="2">工具之---地表最强CMDB自动抓取工具</a><br></p> <p><br></p> </section> </section> <section powered-by="xiumi.us" style="font-weight: 400;font-size: 16px;margin-top: 10px;margin-bottom: 10px;white-space: normal;text-align: right;box-sizing: border-box;"> <a href="http://mp.weixin.qq.com/s?__biz=MzU5NDg5MzM5NQ==&amp;mid=2247484740&amp;idx=1&amp;sn=0683fbf63643218045c1b8cd522137ec&amp;chksm=fe7b0a78c90c836e85c254cce4b8c6897579fd4f6a1386b59084b6fe4cfdd3a72bbcbfbce96f&amp;scene=21#wechat_redirect" target="_blank" data-itemshowtype="0" data-linktype="2" style="background-color: rgb(255, 255, 255);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 12px;letter-spacing: 0.544px;text-align: justify;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></a> <br> </section> <section style="font-weight: 400;font-size: 16px;margin-top: 10px;margin-bottom: 10px;text-align: right;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: middle;box-sizing: border-box;"> <section style="display: inline-block;vertical-align: bottom;padding-left: 5px;padding-right: 5px;line-height: 1.2em;margin-bottom: 2px;color: rgb(121, 121, 121);box-sizing: border-box;"> <p style="margin: 0px;padding: 0px;box-sizing: border-box;">点小花花,让他们知道你<span style="color: rgb(139, 207, 224);box-sizing: border-box;"><strong style="box-sizing: border-box;">“在看”</strong></span>我</p> </section> <section style="max-width: 100%;display: inline-block;vertical-align: bottom;line-height: 0;width: 8%;box-sizing: border-box;"> <img data-ratio="1.321875" data-w="320" src="/upload/5103810f55f9d6b6b422944c97ec479e.gif" style="vertical-align: middle;max-width: 100%;width: 100%;box-sizing: border-box;" width="100%" data-type="gif"> </section> </section> </section> </section>

Java学习指南

作者:cdhqyj

Java学习指南。 学习Java的正确姿势有哪些?学习Java的一般分为两类:一是初学者,二是有一定经验的。但无论是哪类人群,我们需要明白的是他们一定是对这一方向感兴趣的。 首先你将学习HTML、CSS、jQuery和Git。你将构建一个简单的HTML / CSS网站,一个交互式的JavaScript / JavaScript站点,以及一个中等复杂的JavaScript问答应用程序。当你掌握以上基础知识后,就会有一些成就感,这样,你才有继续学下去的动力。要时刻记住:爱好是关键,兴趣是第一。 当你有了成就感,接下来你会变得更加自信。你就会发现编程的世界如此的有趣。 通过一些基本的训练,了解Java及其相关知识后,最重要的一步来了,那就是然后参与一些项目的实战,你将学到足够的知识来开发各种实战项目,有一点经验和几个完成的项目,那么你将成为一个受欢迎的程序员。为何这么说?因为目前市场对Java开发人员的需求量很大。但这并不是说只要你会开发项目、有经验就能被企业录用。你必须通过开发一些令人印象深刻(有趣但不复杂,但并不一定很复杂)的项目来证明你的价值。 那么如何才能开发出企业能看中、自己也满意的项目呢?首先,必要的技术知识点一定要搞懂;其次,多阅读一些关于Java等方向的书籍,可以帮助你进一步深入了解相关内容;最后,最好进行全面而系统的学习。 Java学习需要日积月累,无论学习什么知识都要脚踏实地。除了学习理论知识、来开发实战项目,多阅读相关方面的书籍也很重要。

我为什么用ES做Redis监控,不用Prometheus或Zabbix?

作者:微信小助手

<section style="display: none;" data-tools="新媒体管家" data-label="powered by xmt.cn"> <br> </section> <section style="box-sizing: border-box;font-size: 16px;"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="padding-top: 10px;padding-right: 10px;padding-left: 10px;background-color: rgb(239, 239, 239);box-sizing: border-box;"> <span style="display: inline-block;width: 5%;line-height: 0.8;font-weight: bolder;font-size: 48px;box-sizing: border-box;" title="" opera-tn-ra-cell="_$.pages:0.layers:0.comps:0.txt1"> <section style="box-sizing: border-box;"> “ </section></span> <section style="display: inline-block;vertical-align: top;float: right;width: 90%;line-height: 1.5;font-size: 15px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><span style="letter-spacing: 1px;">Redis 当下很流行,也很好用,无论是在业务应用系统,还是在大数据领域都有重要的地位;但 Redis 也很脆弱,用不好,问题多多。</span></p> </section> <section style="clear: both;box-sizing: border-box;line-height: 0;"> <section style="line-height: 0;width: 0px;"> <svg viewbox="0 0 1 1" style="vertical-align:top;"></svg> </section> </section> </section> </section> </section> <section data-role="outer" label="Powered by 135editor.com"> <section data-tools="135编辑器" data-id="7" data-color="#138bd5"> <section> <section> <section style="line-height: 1.75em;"> <br> </section> <section style="text-align: center;margin-left: 8px;margin-right: 8px;"> <img class="rich_pages" data-ratio="0.5483091787439613" data-s="300,640" src="/upload/62f5367795618410b15ff130d1baf1e8.png" data-type="png" data-w="1242" style=""> </section> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;"><em>图片来自 Pexels</em></span></p> </section> </section> </section> </section> <section data-role="outer" label="Powered by 135editor.com"> <section data-role="paragraph"> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span></p> <section style="line-height: normal;"> <br> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">2012 年以前都是以 Memcached 为主,之后转到 Redis 阵营,经历过单实例模式、主从模式、哨兵模式、代理模式,集群模式,真正公司层面用得好的很少,对于 Redis 掌控都很片面,导致实际项目中问题不少。</span> </section> <p style="white-space: normal;line-height: 1.75em;text-align: center;margin-left: 8px;margin-right: 8px;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.36407300672430354" data-s="300,640" src="/upload/27de4c29ce32b02976d9962d5b52e9b4.png" data-type="png" data-w="1041"></p> <p style="margin-right: 8px;margin-left: 8px;white-space: normal;line-height: 1.75em;text-align: center;"><span style="font-size: 14px;"><em><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">Redis 热度排名</span></em></span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">Redis 要想用得好,需要整体掌握三个层面:</span></p> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li style="font-weight: bold;"><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">开发层面</span></strong></p></li> <li style="font-weight: bold;"><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">架构层面</span></strong></p></li> <li style="font-weight: bold;"><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">运维层面</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span></p></li> </ul> <section data-role="list"> <p style="line-height: normal;"><br></p> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">其中架构与运维至关重要,多数中小型企业仅在开发层面满足常用功能,数据规模稍微大些,业务复杂度高些,就容易出现各种架构与运维问题。</span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">本文主旨是探讨 Redis 监控体系,目前业界当然也有很多成熟的产品,但个人觉得都很常规,只做到一些粗粒度的监控,没有依据业务需求特点因地制宜去细化,从而反向的提供架构开发优化方案。</span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">本文内容将围绕如下几个问题展开讨论:</span> </section> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Redis 监控体系有哪些方面?</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">构建 Redis 监控体系我们做了哪些工作?</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Redis 监控体系应该细化到什么程度?</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">为什么使用 ELK 构建监控体系?</span></p></li> </ul> <section data-role="list"> <p style="line-height: normal;"><br></p> </section> <section data-tools="135编辑器" data-id="86318" data-color="#138bde" data-custom="#138bde"> <section> <section> <section style="box-sizing: border-box;font-size: 16px;"> <section style="border-bottom: 1px solid black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;border-bottom: 6px solid rgb(89, 89, 89);margin-bottom: -1px;border-top-color: rgb(89, 89, 89);border-right-color: rgb(89, 89, 89);border-left-color: rgb(89, 89, 89);font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">需求背景</p> </section> </section> </section> </section> </section> </section> <section data-tools="135编辑器" data-id="39"> <section data-tools="135编辑器" data-id="39" data-color="#1e9be8" data-custom="#1e9be8"> <section> <section style="line-height: normal;"> <br> </section> <section style="box-sizing: border-box;font-size: 16px;"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> </strong> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>项目描述</strong></p> </section> </section> </section> <p style="line-height: normal;"><br></p> </section> </section> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">公司业务范围属于车联网行业,有上百万级的真实车主用户,业务项目围绕车主生活服务展开,为了提高系统性能,引入了 Redis 作为缓存中间件。</span></p> <p style="margin-right: 8px;margin-left: 8px;white-space: normal;line-height: 1.75em;text-align: center;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.6311300639658849" data-s="300,640" src="/upload/6585c252ec372cd3d4e0db35251ac954.png" data-type="png" data-w="469"></p> <section style="margin-right: 8px;margin-left: 8px;white-space: normal;line-height: 1.75em;text-align: center;"> <span style="font-size: 14px;"><em><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">Redis 集群架构与应用架构示意图</span></em></span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">具体描述如下:</span> </section> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">部署架构采用 Redis-Cluster 模式。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">后台应用系统有几十个,应用实例数超过二百个。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">所有应用系统共用一套缓存集群。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">集群节点数几十个,加上容灾备用环境,节点数量翻倍。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">集群节点内存配置较高。</span></p></li> </ul> <section data-role="list"> <section style="line-height: normal;"> <br> </section> <section style="box-sizing: border-box;font-size: 16px;"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> </strong> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>问题描述</strong></p> </section> </section> </section> <section style="line-height: normal;"> <br> </section> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">系统刚开始关于 Redis 的一切都很正常,随着应用系统接入越来越多,应用系统子模块接入也越来越多,开始出现一些问题,应用系统有感知,集群服务端也有感知。</span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">如下描述:</span> </section> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">集群节点崩溃。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">集群节点假死。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">某些后端应用访问集群响应特别慢。</span></p></li> </ul> <section data-role="list"> <p style="line-height: normal;"><br></p> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">其实问题的根源都是架构运维层面的欠缺,对于 Redis 集群服务端的运行监控其实很好做,本身也提供了很多直接的命令方式。</span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">但只能看到服务端的一些常用指标信息,无法深入分析,治标不治本,对于 Redis 的内部运行一无所知。</span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">特别是对于业务应用如何使用 Redis 集群一无所知:</span> </section> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Redis 集群使用的热度问题?</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">哪些应用占用的 Redis 内存资源多?</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">哪些应用占用 Redis 访问数最高?</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">哪些应用使用 Redis 类型不合理?</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">应用系统模块使用 Redis 资源分布怎么样?</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">应用使用 Redis 集群的热点问题?</span></p></li> </ul> <section data-role="list"> <p style="line-height: normal;"><br></p> </section> <section data-tools="135编辑器" data-id="86318" data-color="#138bde" data-custom="#138bde"> <section> <section> <section style="box-sizing: border-box;font-size: 16px;"> <section style="border-bottom: 1px solid black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;border-bottom: 6px solid rgb(89, 89, 89);margin-bottom: -1px;border-top-color: rgb(89, 89, 89);border-right-color: rgb(89, 89, 89);border-left-color: rgb(89, 89, 89);font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">监控体系</p> </section> </section> </section> <p style="line-height: normal;"><br></p> </section> </section> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">监控的目的不仅仅是监控 Redis 本身,而是为了更好的使用 Redis。</span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">传统的监控一般比较单一化,没有系统化,但对于 Redis 来说,个人认为至少包括:</span> </section> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">服务端</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">应用端</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">服务端与应用端联合分析<br></span></p></li> </ul> <p style="line-height: normal;"><br></p> <section style="box-sizing: border-box;font-size: 16px;"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> </strong> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>服务端</strong></p> </section> </section> </section> <p style="line-height: normal;"><br></p> <section data-role="list"> <p style="text-align: justify;line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">服务端首先是操作系统层面,常用的 CPU、内存、网络 IO,磁盘 IO,服务端运行的进程信息等</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Redis 运行进程信息,包括服务端运行信息、客户端连接数、内存消耗、持久化信息 、键值数量、主从同步、命令统计、集群信息等;</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Redis 运行日志,日志中会记录一些重要的操作进程,如运行持久化时,可以有效帮助分析崩溃假死的程序。</span></p> </section> <p style="line-height: normal;"><br></p> <section style="box-sizing: border-box;font-size: 16px;"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>应用端</strong></p> </section> </section> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">应用端、获取应用端使用 Redis 的一些行为,具体哪些应用哪些模块最占用 Redis 资源、哪些应用哪些模块最消耗 Redis 资源、哪些应用哪些模块用法有误等。</span> </section> <p style="line-height: normal;"><br></p> <section style="box-sizing: border-box;font-size: 16px;"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> </strong> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>联合分析</strong></p> </section> </section> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">联合分析结合服务端的运行与应用端使用的行为,如:一些造成服务端突然阻塞的原因,可能是应用端设置了一个很大的缓存键值,或者使用的键值列表,数据量超大造成阻塞。</span> </section> <p style="line-height: normal;"><br></p> <section style="box-sizing: border-box;font-size: 16px;"> <section style="border-bottom: 1px solid black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;border-bottom: 6px solid rgb(89, 89, 89);margin-bottom: -1px;border-top-color: rgb(89, 89, 89);border-right-color: rgb(89, 89, 89);border-left-color: rgb(89, 89, 89);font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">解决方案</p> </section> </section> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">为什么会选择 Elastic-Stack 技术栈呢?<br></span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">多数的第三方只监控一些指标,对于明细日志还是采用 ELK(Elasticsearch、Logstash、Kibana),也就是说用第三方监控指标之后,还得再搭建一个 ELK 集群看明细日志。</span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">再就是说 Elastic-Stack 技术栈整合的优势,指标也可以、日志文件也可以,从采集开始到存储、到最终报表面板都整合得非常好,门槛很低。</span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">下面详细聊聊我们具体怎么做的,做了哪些工作?</span> </section> <p style="line-height: normal;"><br></p> <section style="box-sizing: border-box;font-size: 16px;"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> </strong> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>服务端系统</strong></p> </section> </section> </section> <section data-tools="135编辑器" data-id="39"> <section data-tools="135编辑器" data-id="39" data-color="#1e9be8" data-custom="#1e9be8"> <section> <section style="line-height: normal;"> <br> </section> </section> </section> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Elastic-Stack 家族有 MetricBeat 产品,支持系统层面的信息收集,简单的配置下 Elastic 集群地址和系统指标模块即可上线,并且会在 Kibana 中创建已有的系统监控面板,非常简单快速,一般运维就可以搞定。</span> </section> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.4169184290030212" data-s="300,640" src="/upload/2cf1b59d9fba9947988251c8f7c477a7.png" data-type="png" data-w="331" style=""></p> <section style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 14px;"><em><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">MetrciBeat 示意图</span></em></span> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">系统指标信息收集配置样例如下:</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.5044943820224719" data-s="300,640" src="/upload/c5b222e830727f16ecfc097e813223a6.png" data-type="png" data-w="890" style=""></p> <section data-tools="135编辑器" data-id="39"> <section data-tools="135编辑器" data-id="39" data-color="#1e9be8" data-custom="#1e9be8"> <section> <section style="box-sizing: border-box;font-size: 16px;"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> </strong> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>服务端集群</strong></p> </section> </section> </section> <section style="line-height: normal;"> <br> </section> </section> </section> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">收集 Redis 集群运行信息,业界通常做法都是采用 Redis 提供的 info 命令,定期收集。</span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">info 获取的信息包括如下:</span> </section> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">server:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Redis 服务器的一般信息</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">clients:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">客户端的连接部分</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">memory:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">内存消耗相关信息</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">persistence:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">RDB 和 AOF 相关信息</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">stats:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">一般统计</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">replication:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">主/从复制信息</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">cpu:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">统计 CPU 的消耗 command</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">stats:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Redis 命令</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">统计 cluster:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Redis 集群信息</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">keyspace:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">数据库的相关统计</span></p></li> </ul> <section data-role="list"> <p style="line-height: normal;"><br></p> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Elastic-Stack 家族的 MetricBeat 产品也支持 Redis 模块,也是采用 info 命令获取的。</span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">但是有一些实现的局限性,如下描述:</span> </section> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Redis 集群的主从关系信息,MetricBeats 表达不出来。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Redis 集群的一些统计信息,永远是累计增加的,如命令数,如果要获取命令数的波峰值,则无法得到;</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Redis 集群状态信息变化,MetricBeats 是无法动态的,如集群新增节点、下线节点等。</span></p></li> </ul> <section data-role="list"> <p style="line-height: normal;"><br></p> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">所以这里参考了 CacheCloud 产品(搜狐团队开源),我们自定义设计开发了 Agent,定时从 Redis 集群采集信息,并在内部做一些统计数值的简单计算,转换成 Json,写入到本地文件,通过 Logstash 采集发送到 Elasticsearch。</span></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <br> </section> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.21495327102803738" data-s="300,640" src="/upload/4fe2b825e16eb1f6a911fb98e40fe49c.png" data-type="png" data-w="642" style=""></p> <section style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 14px;"><em><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">Redis 服务端运行信息采集架构示意图</span></em></span> </section> <section data-tools="135编辑器" data-id="39"> <section data-tools="135编辑器" data-id="39" data-color="#1e9be8" data-custom="#1e9be8"> <section> <section style="line-height: normal;"> <br> </section> <section style="box-sizing: border-box;font-size: 16px;"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> </strong> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>服务端日志</strong></p> </section> </section> </section> <p style="line-height: normal;"><br></p> </section> </section> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Redis 服务端运行日志采集很简单,直接通过 Elastic-Stack 家族的 Filebeat 产品,其中有 Redis 模块,配置一下 Elastic 服务端,日志文件地址即可。</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.25461254612546125" data-s="300,640" src="/upload/da116a665474465eee0f13241b64a2c9.png" data-type="png" data-w="542" style=""></p> <section style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 14px;"><em><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">服务端日志采集过程</span></em></span> </section> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">Redis 运行日志采集配置:</span></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.3132328308207705" data-s="300,640" src="/upload/c217280310078df01e60600ec198a9f7.png" data-type="png" data-w="597" style=""></p> <section data-tools="135编辑器" data-id="39"> <section data-tools="135编辑器" data-id="39" data-color="#1e9be8" data-custom="#1e9be8"> <section> <section style="box-sizing: border-box;font-size: 16px;"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> </strong> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>应用端</strong></p> </section> </section> </section> <p style="line-height: normal;"><br></p> </section> </section> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">应用端信息采集是整个 Redis 监控体系最重要的部分,也是实现最麻烦、链路最长的。</span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">首先是修改 Jedis(技术栈 Java)源码,增加埋点代码,重新编译并引用到应用项目中,应用端对于 Redis 集群的任何命令操作,都会被捕捉,并记录下关键信息,之后写入到本地文件。</span> </section> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.4288461538461538" data-s="300,640" src="/upload/6ccda2bf737f659215ee7fff6b6d2324.png" data-type="png" data-w="520" style=""></p> <section style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 14px;"><em><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">Redis 应用端行为采集架构图</span></em></span> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">应用端采集的数据格式如下:</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.4724669603524229" data-s="300,640" src="/upload/fd9ff76e071327c5b8b8e2864fff2249.png" data-type="png" data-w="908" style=""></p> <section style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 14px;"><em><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">应用端采集的数据案例</span></em></span> </section> <section style="line-height: normal;"> <br> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">①Jedis 修改</span></strong> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">Jedis 改造记录的信息如下:</span> </section> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">r_host:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">访问 Redis 集群的服务器地址与端口,其中某一台 ip:port。</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">r_cmd:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">执行命令类型、如 get、set、hget、hset 等各种。</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">r_start:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">执行命令开始时间。</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">r_cost:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">时间消耗。</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">r_size:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">获取键值大小或者设置键值大小。</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">r_key:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">获取键值名称。</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">r_keys:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">键值的二级拆分,数组的长度不限制。这里有必要强调一下,所有应用系统共用的是一套集群,所以应用系统的键值都是有规范的,按照特殊符号分割,如:"应用名称_系统模块_动态变量_xxx“,主要便于我们区分。</span></p></li> </ul> <section data-role="list"> <p style="line-height: normal;"><br></p> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">在 Jedis 改造有几处地方,如下:</span> </section> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">类 Connection.java 文件,统计开始,记录命令执行开始时间;统计结束,记录命令结束时间、时间消耗等,并写入到日志流中。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">类 JedisClusterCommand 文件,获取键的地方 key,方便之后分析应用键的行为。</span></p></li> </ul> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">在类 Connection.java 文件中有两处:</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.3935643564356436" data-s="300,640" src="/upload/ab37cf24c40f21cc3d86d780eff7172.png" data-type="png" data-w="808" style=""></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 14px;"><em><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">类Connection.java 文件埋点代码的地方</span></em></span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.7952853598014888" data-s="300,640" src="/upload/4394a4705197b0a06d5a5941a20c892b.png" data-type="png" data-w="806" style=""></p> <section style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 14px;"><em><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">类 Connection.java 文件埋点代码的地方</span></em></span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">类 JedisClusterCommand 文件埋点代码 .java 文件中有 1 处:</span> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.20668058455114824" data-s="300,640" src="/upload/75a6af6f513f17a961af626d43fe3a45.png" data-type="png" data-w="958" style=""></p> <section style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 14px;"><em><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">类 JedisClusterCommand 文件埋点代码</span></em></span> </section> <section style="line-height: normal;"> <br> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">②Logback 修改</span></strong> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span> </section> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">应用端都会使用 Logback 写入日志文件,同时为了更加精准,应用端写入日志时还需要获取应用端的一些信息,如下:</span></p> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">app_ip:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">应用端部署在服务器上的 IP 地址。</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">app_host:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">应用端部署在服务器上的服务器名称。</span></p></li> </ul> <section data-role="list"> <p style="line-height: normal;"><br></p> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">自定义一个 Layout,自动获取应用端的 IP 地址与服务器名称:</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.19900497512437812" data-s="300,640" src="/upload/d7e107022b996a991e52aeea6cd94320.png" data-type="png" data-w="804" style=""></p> <section style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 14px;"><em><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">自定义 Logback 的 Layout</span></em></span> </section> <section style="line-height: normal;"> <br> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">③App 配置</span></strong> </section> <section style="line-height: normal;"> <br> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">App 配置属于最后收尾工作,主要是输出埋点的日志数据,配置日志 logback.xml 文件即可:</span> </section> </section> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.1505016722408027" data-s="300,640" src="/upload/9ee1b07a3ca46bf3b839aed0a2c679ef.png" data-type="png" data-w="897" style=""></p> <section data-role="paragraph"> <section style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 14px;"><em><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">配置应用端日志文件 logback.xml</span></em></span> </section> <section style="line-height: normal;"> <br> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">④日志采集</span></strong> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span> </section> <section style="line-height: normal;"> <br> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">应用端日志采集采用 Logstash,配置日志目录,指向 Elastic 集群,这样整体的监控日志采集部分就结束了。</span> </section> <section data-tools="135编辑器" data-id="39"> <section data-tools="135编辑器" data-id="39" data-color="#1e9be8" data-custom="#1e9be8"> <section> <section style="line-height: normal;"> <br> </section> <section style="box-sizing: border-box;font-size: 16px;"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> </strong> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>日志分析</strong></p> </section> </section> </section> <p style="line-height: normal;"><br></p> </section> </section> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Redis 服务端的日志分析比较简单,常规的一些指标而已,创建好关键的图表,容易看出问题。重点讨论应用端的日志分析。</span></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><img class="rich_pages js_insertlocalimg" data-ratio="0.8056749785038693" data-s="300,640" src="/upload/93d558d28effdaeeecb42687523ffbfe.png" data-type="png" data-w="1163" style=""></p> <section style="text-align: center;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 14px;"><em><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">应用端使用 Redis 一些行为图表</span></em></span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">ELK 监控体系上线之后,我们连续观察分析两周,获得了一些监控成果,如:</span> </section> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">应用端部分键值太大,居然超过 1MB,这种键值访问一次消耗时间很大,会严重造成阻塞。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">部分应用居然使用 Redis 当成数据库使用。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">有将 List 类型当成消息队列使用,一次存取几十万的数据。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">某些应用对于集群的操作频次特别高,几乎占用了一半以上。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">还有很多,就不一一描述了。</span></p></li> </ul> <section data-role="list"> <section style="line-height: normal;"> <br> </section> <section style="box-sizing: border-box;font-size: 16px;"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;background-color: rgb(89, 89, 89);box-sizing: border-box;"></span> </strong> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>后续方案</strong></p> </section> </section> </section> <section style="line-height: normal;"> <br> </section> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">监控体系相当于架构师的眼睛,有了这个,Redis 方面的优化改造方案就很好制定了:</span> </section> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">应用端、误用的使用全部要改掉。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">服务端,按照应用的数据,进行一些拆分,拆分出一些专用的集群,特定为一些应用使用或者场景。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">开发者,后续有新业务模块需要接入 Redis 需要告知架构师们评审。</span></p></li> </ul> <section data-role="list"> <p style="line-height: normal;"><br></p> </section> <section data-tools="135编辑器" data-id="86318" data-color="#138bde" data-custom="#138bde"> <section> <section> <section style="box-sizing: border-box;font-size: 16px;"> <section style="border-bottom: 1px solid black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;border-bottom: 6px solid rgb(89, 89, 89);margin-bottom: -1px;border-top-color: rgb(89, 89, 89);border-right-color: rgb(89, 89, 89);border-left-color: rgb(89, 89, 89);font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">结语</p> </section> </section> </section> <p style="line-height: normal;"><br></p> </section> </section> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">监控体系项目前后经历过几个月,服务端部分短期内就完成的,应用端是随着应用发布逐步完成的。上线完成之后又经历几周的跟踪分析,才确定下来整体的优化方案。<br></span> </section> <section style="line-height: normal;"> <br> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">监控体系本身并不是为了监控,而是发现问题、预见问题,最终提前解决问题,监控做得好,下班下得早。</span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Redis 集群是个好东西,完全掌握还是需要很长的时间,特别是架构、运维层面,如果没有,请做好监控。</span> </section> <section style="line-height: normal;"> <br> </section> <p style="white-space: normal;line-height: 1.75em;"><span style="color: rgb(89, 89, 89);letter-spacing: 1px;"><em><span style="font-size: 14px;">作者:李猛</span></em></span><br></p> <p style="white-space: normal;line-height: 1.75em;"><span style="color: rgb(89, 89, 89);letter-spacing: 1px;"><em><span style="font-size: 14px;">简介:数据技术专家,Elastic-Stack 产品深度用户,ES 认证工程师,对 Elastic-Stack 开发、架构、运维有深入体验;实践过多种 ES 项目,最暴力的大数据分析应用,最复杂的业务系统应用。</span></em></span></p> <p style="white-space: normal;line-height: 1.75em;"><span style="color: rgb(89, 89, 89);letter-spacing: 1px;"><em><span style="font-size: 14px;">编辑:<em>陶家龙</em></span></em></span></p> <p style="white-space: normal;line-height: 27.2px;text-align: start;"><em><span style="line-height: 1.75em;font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">出处:</span><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 0.544px;line-height: 20px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;">转载自微信公众号 DBAplus 社群(ID:dbaplus),本文根据李猛老师在〖deeplus 直播第 220 期〗线上分享演讲内容整理而成。</span></em></p> <p style="text-align: center;"><img class="rich_pages" data-ratio="0.39375" src="/upload/eccf90ae5f48405df149baa3056d4bf3.gif" data-type="gif" data-w="640" style=""></p> <section data-role="outer" label="Powered by 135editor.com"> <section data-role="paragraph"> <section style="box-sizing: border-box;font-size: 16px;"> <section style="margin-top: 0.5em;margin-bottom: 0.5em;box-sizing: border-box;" powered-by="xiumi.us"> <section style="font-size: 15px;border-style: solid;border-width: 0px 0px 1px;color: rgb(89, 89, 89);border-bottom-color: rgba(215, 215, 215, 0.960784);box-sizing: border-box;"> <p style="box-sizing: border-box;"><span style="letter-spacing: 1px;"><strong>精彩文章推荐:</strong></span></p> </section> </section> </section> <section style="line-height: 2em;"> <a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MjM5ODI5Njc2MA==&amp;mid=2655832435&amp;idx=1&amp;sn=2f2053c38efc93b935464955dd2ea7e1&amp;chksm=bd7484a48a030db2079554b027dc6073bee0ec66ab530bcfefe667266ee9dff133c42fd884b7&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;" data-linktype="2"><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">求求你们了,别再写满屏的try catch了...</span></a> <br> </section> <section style="line-height: 2em;"> <a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MjM5ODI5Njc2MA==&amp;mid=2655832365&amp;idx=1&amp;sn=c159666295763c4d025a7a451bb5ae38&amp;chksm=bd7484fa8a030dec40555dcbb07cc143ec665e66d7053575783bd9ae06e346a33b0e4c6a6532&amp;scene=21#wechat_redirect" data-itemshowtype="11" tab="innerlink" style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;" data-linktype="2"><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">技术总监夸我“索引”用的溜,我飘了......</span></a> <br> </section> <section style="line-height: 2em;"> <a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MjM5ODI5Njc2MA==&amp;mid=2655832199&amp;idx=1&amp;sn=0ce12bb0d2da9b10071033a04d7923c6&amp;chksm=bd7485508a030c460b988710c60a4d925b5f2a836ce150a7e288f89a08ba88002311260d52aa&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;" data-linktype="2"><span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;">如何用ELK搭建TB级的日志监控系统?</span></a> <br> </section> </section> </section> </section> </section>

如此通俗的分布式锁讲解,如果还搞不定那就...

作者:微信小助手

<section style="display: none;" data-tools="新媒体管家" data-label="powered by xmt.cn" data-mpa-powered-by="yiban.io"> <br> </section> <p style="text-align: center;"><span style="font-size: 13px;color: rgb(136, 136, 136);font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;letter-spacing: 0.544px;">点击上方蓝色“</span><span style="font-size: 13px;font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;letter-spacing: 0.544px;color: rgb(0, 128, 255);">程序猿DD</span><span style="font-size: 13px;color: rgb(136, 136, 136);font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;letter-spacing: 0.544px;">”,选择“设为星标”</span><strong style="max-width: 100%;letter-spacing: 0.544px;color: rgb(74, 74, 74);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;font-size: 16px;white-space: pre-line;background-color: rgb(255, 255, 255);text-align: right;box-sizing: border-box !important;overflow-wrap: break-word !important;"></strong></p> <p style="max-width: 100%;min-height: 1em;white-space: normal;text-align: center;overflow-wrap: break-word !important;box-sizing: border-box !important;"><span style="max-width: 100%;font-size: 13px;overflow-wrap: break-word !important;box-sizing: border-box !important;"><span style="max-width: 100%;color: rgb(136, 136, 136);font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;letter-spacing: 0.544px;overflow-wrap: break-word !important;box-sizing: border-box !important;">回复“</span><span style="max-width: 100%;font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;letter-spacing: 0.544px;color: rgb(0, 128, 255);overflow-wrap: break-word !important;box-sizing: border-box !important;">资源</span><span style="max-width: 100%;color: rgb(136, 136, 136);font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;letter-spacing: 0.544px;overflow-wrap: break-word !important;box-sizing: border-box !important;">”获取独家整理的学习资料!</span></span></p> <p style="margin-top: 10px;margin-bottom: 10px;max-width: 100%;min-height: 1em;white-space: normal;text-align: center;overflow-wrap: break-word !important;box-sizing: border-box !important;"><span style="max-width: 100%;color: rgb(136, 136, 136);font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;font-size: 14px;letter-spacing: 0.544px;overflow-wrap: break-word !important;box-sizing: border-box !important;"><img data-backh="34" data-backw="540" data-ratio="0.0625" data-s="300,640" data-type="jpeg" data-w="640" width="100%" src="/upload/8c292e55ba5a23cb6ebc11f2a2c4fece.jpg" style="font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;overflow-wrap: break-word !important;box-sizing: border-box !important;visibility: visible !important;width: 654px !important;"></span></p> <p style="max-width: 100%;min-height: 1em;white-space: normal;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);text-align: left;overflow-wrap: break-word !important;box-sizing: border-box !important;"><span style="max-width: 100%;letter-spacing: 0.544px;color: rgb(178, 178, 178);font-size: 13px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;overflow-wrap: break-word !important;box-sizing: border-box !important;">作者 |&nbsp;<span style="color: rgb(178, 178, 178);max-width: 100%;letter-spacing: 0.544px;text-align: start;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;box-sizing: border-box !important;">贾俊江</span><br style="max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;"></span></p> <section style="text-align: left;margin-bottom: 15px;max-width: 100%;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;box-sizing: border-box !important;"> <span style="max-width: 100%;letter-spacing: 0.544px;color: rgb(178, 178, 178);font-size: 13px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;overflow-wrap: break-word !important;box-sizing: border-box !important;">来源 |<span style="color: rgb(178, 178, 178);max-width: 100%;letter-spacing: 0.544px;white-space: pre-line;overflow-wrap: break-word !important;box-sizing: border-box !important;">&nbsp;<span style="color: rgb(178, 178, 178);max-width: 100%;letter-spacing: 0.544px;text-align: right;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;box-sizing: border-box !important;">http://tinyurl.com/y628pqmx</span></span></span> </section> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">首先,分布式锁和我们平常讲到的锁原理基本一样,目的就是确保在多个线程并发时,只有一个线程在同一刻操作这个业务或者说方法、变量。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">在一个进程中,也就是一个jvm或者说应用中,我们很容易去处理控制,在jdk java.util并发包中已经为我们提供了这些方法去加锁,比如synchronized关键字或者Lock锁,都可以处理。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">但是我们现在的应用程序如果只部署一台服务器,那并发量是很差的,如果同时有上万的请求,很有可能造成服务器压力过大而瘫痪。想想双十一和大年三十晚上十点,瓜分支付宝红包等业务场景,自然需要用到多台服务器去同时处理这些业务,这些服务可能会有上百台同时处理。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">但是我们想一想,如果有100台服务器要处理分红包的业务,现在假设有1亿的红包,1千万个人分,金额随机,那么这个业务场景下,是不是必须确保这1千万个人最后分的红包金额总和等于1亿?</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">如果处</span><span style="font-size: 15px;text-decoration: none;">理不好每人分到100万,那马云爸爸估计大年初一,就得宣布破产了</span></p> <p style="text-align: center;"><img class="rich_pages" data-ratio="0.5911214953271028" data-s="300,640" src="/upload/f12542e0bd6dff5b5223a3312422b2e5.png" data-type="png" data-w="856" style=""></p> <h1 style="margin-top: 35px;margin-bottom: 15px;padding-bottom: 0.5em;font-weight: bold;font-size: 1.2rem;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(52, 73, 94);cursor: text;line-height: 1.225;border-bottom: 1px solid rgb(221, 221, 221);"><span style="font-size: 15px;">一、常规锁会造成什么情况?</span><br></h1> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">首先说一下我们为什么要搞集群。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">简单理解就是,需求量(请求并发量)变大了,一个工人处理能力有限,那就多招一些工人来一起处理。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">假设1千万个请求平均分配到100台服务器上,每个服务器接收10w的请求。这10w个请求并不是在同一秒中来的,可能是在1,2个小时内,可以联想下我们三十晚上开红包,等到10:20开始,有的人立马开了,有的人等到12点才想起来。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">那这样的话,平均到每一秒上的请求也就不到1千个,这种压力一般的服务器还是可以承受的。</span></p> <ul class="list-paddingleft-2" style="font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"> <li style="font-size: 15px;"><p><span style="font-size: 15px;">第一个用户来分,请求到来后,需要在1亿里面给他分一部分钱,金额随机,假设第一个人分到了100,那就要在这1亿中减去100块,剩下99999900块~</span></p></li> <li style="font-size: 15px;"><p><span style="font-size: 15px;">第二个用户再来分,金额随机,这次分200块,那就需要在剩下的99999900块中再减去200块,剩下99999700块。</span></p></li> <li style="font-size: 15px;"><p><span style="font-size: 15px;">等到第10w个用户来,一看还有1000w,那这1000w全成他的了。</span></p></li> </ul> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">等于是在每个服务器中去分1亿,也就是10w个用户分了一个亿,最后总计有100个服务器,要分100亿。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">如果真这样了,虽说马云爸爸不会破产(据最新统计马云有2300亿人民币),那分红包的开发项目组,以及产品经理,可以GG了~</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">关注公众号:后端面试那些事儿,每日面试要点推送,一起进大厂!</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">简化结构图如下:</span></p> <figure style="margin-top: 10px;margin-bottom: 10px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"> <img data-ratio="0.42833607907743" src="/upload/d709cd23c7e6f87b7154d65d705a75ff.png" data-type="png" data-w="607"> </figure> <h1 style="margin-top: 35px;margin-bottom: 15px;padding-bottom: 0.5em;font-weight: bold;font-size: 1.2rem;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(52, 73, 94);cursor: text;line-height: 1.225;border-bottom: 1px solid rgb(221, 221, 221);"><span style="font-size: 15px;">二、分布式锁怎么去处理?</span></h1> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">那么为了解决这个问题,让1000万用户只分1亿,而不是100亿,这个时候分布式锁就派上用处了。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">分布式锁可以把整个集群就当作是一个应用一样去处理,那么也就需要这个锁独立于每一个服务之外,而不是在服务里面。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">假设第一个服务器接收到用户1的请求后,不能只在自己的应用中去判断还有多少钱可以分了,而需要去外部请求专门负责管理这1亿红包的人(服务),问他:哎,我这里要分100块,给我100。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">管理红包的妹子(服务)一看,还有1个亿,那好,给你100块,然后剩下99999900块。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">第二个请求到来后,被服务器2获取,继续去询问,管理红包的妹子,我这边要分10块,管理红包的妹子先查了下还有99999900,那就说:好,给你10块。那就剩下99999890块。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">等到第1000w个请求到来后,服务器100拿到请求,继续去询问,管理红包的妹子,我要100,妹子翻了翻白眼,对你说,就剩1块了,爱要不要,那这个时候就只能给你1块了(1块也是钱啊,买根辣条还是可以的)。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;color: rgb(255, 104, 39);">这些请求编号1,2不代表执行的先后顺序,正式的场景下,应该是100台服务器每个服务器持有一个请求去访问负责管理红包的妹子(服务),那在管红包的妹子那里同时会接收到100个请求,这个时候就需要在负责红包的妹子那里加个锁就可以了(抛绣球),你们100个服务器谁拿到锁(抢到绣球),谁就进来和我谈,我给你分,其他人就等着去吧。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">经过上面的分布式锁的处理后,马云爸爸终于放心了,决定给红包团队每人加一个鸡腿。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">简化的结构图如下:</span></p> <figure style="margin-top: 10px;margin-bottom: 10px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"> <img data-ratio="0.31208499335989376" src="/upload/80ae5f784fbba661c270d2cbec22d3e6.png" data-type="png" data-w="753"> </figure> <h1 style="margin-top: 35px;margin-bottom: 15px;padding-bottom: 0.5em;font-weight: bold;font-size: 1.2rem;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(52, 73, 94);cursor: text;line-height: 1.225;border-bottom: 1px solid rgb(221, 221, 221);"><span style="font-size: 15px;">三、分布式锁的实现有哪些?</span></h1> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">说到分布式锁的实现,还是有很多的,有数据库方式的,有Redis分布式锁,有Zookeeper分布式锁等等。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">我们如果采用Redis作为分布式锁,那么上图中负“责红包的妹子(服务)”,就可以替换成Redis,请自行脑补。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;"><strong>1、为什么Redis可以实现分布式锁?</strong></span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">首先Redis是单线程的,这里的单线程指的是网络请求模块使用了一个线程(所以不需考虑并发安全性),即一个线程处理所有网络请求,其他模块仍用了多个线程。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">在实际的操作中过程大致是这样子的:</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">服务器1要去访问发红包的妹子,也就是Redis,那么他会在Redis中通过"setnx key value" 操作设置一个key进去,value是啥不重要,重要的是要有一个key,也就是一个标记,而且这个key你爱叫啥叫啥,只要所有的服务器设置的key相同就可以。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">假设我们设置一个,如下图:</span></p> <figure style="margin-top: 10px;margin-bottom: 10px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"> <img data-ratio="0.15444015444015444" src="/upload/fffeee8be014cb5d5c856130afa0b856.png" data-type="png" data-w="259"> </figure> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">那么我们可以看到会返回一个1,那就代表了成功。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">如果再来一个请求去设置同样的key,如下图:</span></p> <figure style="margin-top: 10px;margin-bottom: 10px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"> <img data-ratio="0.12681159420289856" src="/upload/d7b0e813645bf7b761d293afeebaafad.png" data-type="png" data-w="276"> </figure> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">这个时候会返回0,那就代表失败了。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">那么我们就可以通过这个操作去判断是不是当前可以拿到锁,或者说可以去访问“负责发红包的妹子”,如果返回1,那我就开始去执行后面的逻辑,如果返回0,那就说明已经被人占用了,我就要继续等待。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">当服务器1拿到锁之后,进行了业务处理,完成后,还需要释放锁,如下图所示:</span></p> <figure style="margin-top: 10px;margin-bottom: 10px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"> <img data-ratio="0.11912225705329153" src="/upload/a30dcf50881d7dfb802faa0becbd10fd.png" data-type="png" data-w="319"> </figure> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">删除成功返回1,那么其他的服务器就可以继续重复上面的步骤去设置这个key,以达到获取锁的目的。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;color: rgb(255, 104, 39);">当然以上的操作是在Redis客户端直接进行的,通过程序调用的话,肯定就不能这么写,比如java就需要通过jedis去调用,但是整个处理逻辑基本都是一样的。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">通过上面的方式,我们好像是解决了分布式锁的问题,但是想想还有没有什么问题呢?</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">对,问题还是有的,可能会有死锁的问题发生,比如服务器1设置完之后,获取了锁之后,忽然发生了宕机。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">那后续的删除key操作就没法执行,这个key会一直在Redis中存在,其他服务器每次去检查,都会返回0,他们都会认为有人在使用锁,我需要等。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">为了解决这个死锁的问题,我们就需要给key设置有效期了。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">设置的方式有2种:</span></p> <p><span style="font-size: 15px;color: rgb(255, 104, 39);"><strong>第一种</strong></span><span style="font-size: 15px;">就是在set完key之后,直接设置key的有效期 "expire key timeout" ,为key设置一个超时时间,单位为second,超过这个时间锁会自动释放,避免死锁。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">这种方式相当于,把锁持有的有效期,交给了Redis去控制。如果时间到了,你还没有给我删除key,那Redis就直接给你删了,其他服务器就可以继续去setnx获取锁。</span></p> <p><strong><span style="font-size: 15px;color: rgb(255, 104, 39);">第二种</span></strong><span style="font-size: 15px;">方式,就是把删除key权利交给其他的服务器,那这个时候就需要用到value值了,比如服务器1,设置了value也就是timeout为当前时间+1秒 ,这个时候服务器2通过get发现时间已经超过系统当前时间了,那就说明服务器1没有释放锁,服务器1可能出问题了,服务器2就开始执行删除key操作,并且继续执行setnx操作。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">但是这块有一个问题,也就是不光你服务器2可能会发现服务器1超时了,服务器3也可能会发现,如果刚好服务器2 setnx操作完成,服务器3就接着删除,是不是服务器3也可以setnx成功了?</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">那就等于是服务器2和服务器3都拿到锁了,那就问题大了。这个时候怎么办呢?</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">这个时候需要用到“GETSET &nbsp;key value”命令了。这个命令的意思就是获取当前key的值,并且设置新的值。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">假设服务器2发现key过期了,开始调用getset命令,然后用获取的时间判断是否过期,如果获取的时间仍然是过期的,那就说明拿到锁了。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">如果没有,则说明在服务2执行getset之前,服务器3可能也发现锁过期了,并且在服务器2之前执行了getset操作,重新设置了过期时间。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">那么服务器2就需要放弃后续的操作,继续等待服务器3释放锁或者去监测key的有效期是否过期。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">这块其实有一个小问题是,服务器3已经修改了有效期,拿到锁之后,服务器2也修改了有效期,但是没能拿到锁,但是这个有效期的时间已经被在服务器3的基础上有增加一些,但是这种影响其实还是很小的,几乎可以忽略不计。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;"><strong>2、为什么Zookeeper可实现分布式锁?</strong></span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">百度百科是这么介绍的:ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">那对于我们初次认识的人,可以理解成ZooKeeper就像是我们的电脑文件系统,我们可以在d盘中创建文件夹a,并且可以继续在文件夹a中创建文件夹a1,a2。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">那我们的文件系统有什么特点?那就是同一个目录下文件名称不能重复,同样ZooKeeper也是这样的。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">在ZooKeeper所有的节点,也就是文件夹称作Znode,而且这个Znode节点是可以存储数据的。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">我们可以通过“ create /zkjjj nice”来创建一个节点,这个命令就表示,在跟目录下创建一个zkjjj的节点,值是nice。同样这里的值,和我在前面说的Redis中的一样,没什么意义,你随便给。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">另外ZooKeeper可以创建4种类型的节点,分别是:</span></p> <ul class="list-paddingleft-2" style="font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"> <li style="font-size: 15px;"><p><span style="font-size: 15px;">持久性节点</span></p></li> <li style="font-size: 15px;"><p><span style="font-size: 15px;">持久性顺序节点</span></p></li> <li style="font-size: 15px;"><p><span style="font-size: 15px;">临时性节点</span></p></li> <li style="font-size: 15px;"><p><span style="font-size: 15px;">临时性顺序节点</span></p></li> </ul> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">首先说下持久性节点和临时性节点的区别:</span></p> <ul class="list-paddingleft-2" style="font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);"> <li style="font-size: 15px;"><p><span style="font-size: 15px;">持久性节点表示只要你创建了这个节点,那不管你ZooKeeper的客户端是否断开连接,ZooKeeper的服务端都会记录这个节点;</span></p></li> <li style="font-size: 15px;"><p><span style="font-size: 15px;">临时性节点刚好相反,一旦你ZooKeeper客户端断开了连接,那ZooKeeper服务端就不再保存这个节点;</span></p></li> <li style="font-size: 15px;"><p><span style="font-size: 15px;">顺便也说下顺序性节点,顺序性节点是指,在创建节点的时候,ZooKeeper会自动给节点编号比如0000001,0000002这种的。</span></p></li> </ul> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">Zookeeper有一个监听机制,客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、被删除、子目录节点增加删除)等,Zookeeper会通知客户端。</span></p> <h1 style="margin-top: 35px;margin-bottom: 15px;padding-bottom: 0.5em;font-weight: bold;font-size: 1.2rem;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(52, 73, 94);cursor: text;line-height: 1.225;border-bottom: 1px solid rgb(221, 221, 221);"><span style="font-size: 15px;">四、在Zookeeper中如何加锁?</span></h1> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">下面我们继续结合我们上面的分红包场景,描述下在Zookeeper中如何加锁。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">假设服务器1,创建了一个节点 /zkjjj,成功了,那服务器1就获取了锁,服务器2再去创建相同的锁,就会失败,这个时候就只能监听这个节点的变化。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">等到服务器1处理完业务,删除了节点后,他就会得到通知,然后去创建同样的节点,获取锁处理业务,再删除节点,后续的100台服务器与之类似。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;color: rgb(255, 104, 39);">注意这里的100台服务器并不是挨个去执行上面的创建节点的操作,而是并发的,当服务器1创建成功,那么剩下的99个就都会注册监听这个节点,等通知,以此类推。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">但是大家有没有注意到,这里还是有问题的,还是会有死锁的情况存在,对不对?</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">当服务器1创建了节点后挂了,没能删除,那其他99台服务器就会一直等通知,那就完蛋了。。。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">这个时候就需要用到临时性节点了,我们前面说过了,临时性节点的特点是客户端一旦断开,就会丢失,也就是当服务器1创建了节点后,如果挂了,那这个节点会自动被删除,这样后续的其他服务器,就可以继续去创建节点,获取锁了。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">但是我们可能还需要注意到一点,就是惊群效应:举一个很简单的例子,当你往一群鸽子中间扔一块食物,虽然最终只有一个鸽子抢到食物,但所有鸽子都会被惊动来争夺,没有抢到…</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">就是当服务器1节点有变化,会通知其余的99个服务器,但是最终只有1个服务器会创建成功,这样98还是需要等待监听,那么为了处理这种情况,就需要用到临时顺序性节点。大致意思就是,之前是所有99个服务器都监听一个节点,现在就是每一个服务器监听自己前面的一个节点。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">假设100个服务器同时发来请求,这个时候会在/zkjjj节点下创建100个临时顺序性节点/zkjjj/000000001,/zkjjj/000000002,一直到/zkjjj/000000100,这个编号就等于是已经给他们设置了获取锁的先后顺序了。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;"><span style="font-size: 15px;">当001节点处理完毕,删除节点后,002收到通知,去获取锁,开始执行,执行完毕,删除节点,通知003~以此类推。</span></p> <p style="margin-top: 0.8em;margin-bottom: 0.8em;padding-top: 5px;padding-bottom: 5px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: 26px;text-align: center;"><span style="font-size: 15px;"><strong>So...这下懂了么?不懂你说怎么办吧!</strong></span><br></p> <p style="margin-top: 5px;margin-bottom: 5px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);font-size: 16px;white-space: pre-line;color: rgb(74, 74, 74);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;text-align: start;line-height: normal;overflow-wrap: break-word !important;box-sizing: border-box !important;"><br></p> <section data-recommend-type="list-title" data-mpa-template="t" style="width: 100%;display: flex;justify-content: center;align-items: center;" data-mid="" data-from="yb-recommend"> <section style="width: 100%;background: rgb(255, 255, 255);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(232, 232, 235);padding: 20px 14px;" data-mid=""> <section style="width: 100%;display: flex;justify-content: center;align-items: flex-end;" data-mid=""> <section style="display: flex;justify-content: center;align-items: center;max-width: 100%;background: rgb(255, 255, 255);margin-bottom: -10px;z-index: 10;" data-mid=""> <section style="width: 10px;height: 10px;border-radius: 50%;border-width: 1px;border-style: solid;border-color: rgb(68, 153, 231);" data-mid=""> <br> </section> <section style="margin: 0px 8px;height: 20px;font-size: 14px;font-weight: 500;color: rgb(68, 153, 231);line-height: 20px;" data-mid=""> <p data-mid="">往期推荐</p> </section> <section style="width: 10px;height: 10px;border-radius: 50%;border-width: 1px;border-style: solid;border-color: rgb(68, 153, 231);" data-mid=""> <br> </section> </section> </section> <section style="width: 100%;height: 1px;background: rgb(68, 153, 231);margin-bottom: 16px;" data-mid=""> <br> </section> <section style="width: 100%;" data-mid=""> <a href="http://mp.weixin.qq.com/s?__biz=MzAxODcyNjEzNQ==&amp;mid=2247493862&amp;idx=2&amp;sn=d57e64dc3d65c369009cc35f5c41027e&amp;chksm=9bd3457eaca4cc68e0017a866a405c390958508da39dd4bc3ead69afb96a20755fe7dd5f4148&amp;scene=21#wechat_redirect" data-linktype="2"> <section data-recommend-title="t" style="width: 100%;background: rgb(245, 245, 245);display: flex;justify-content: center;align-items: center;flex-wrap: nowrap;padding: 6px 16px;font-size: 13px;font-weight: 400;color: rgb(68, 153, 231);line-height: 18px;" data-mid=""> <p style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width: 100%;" data-mid="">Java 14 Hotspot 虚拟机垃圾回收调优指南!</p> </section></a> <a href="http://mp.weixin.qq.com/s?__biz=MzAxODcyNjEzNQ==&amp;mid=2247493689&amp;idx=1&amp;sn=1b445ff303151309de160f9df94bc2c7&amp;chksm=9bd345a1aca4ccb7fb586e2521cd29f44073cb3584e5c5f8fea88eb9947b8b37656692c878ad&amp;scene=21#wechat_redirect" data-linktype="2"> <section data-recommend-title="t" style="width: 100%;display: flex;justify-content: center;align-items: center;flex-wrap: nowrap;padding: 6px 16px;font-size: 13px;font-weight: 400;color: rgb(68, 153, 231);line-height: 18px;" data-mid=""> <p style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width: 100%;" data-mid="">Lombok 的爱恨情仇</p> </section></a> <a href="http://mp.weixin.qq.com/s?__biz=MzAxODcyNjEzNQ==&amp;mid=2247493552&amp;idx=1&amp;sn=d114406d45483f006bd0fca26ac8aca2&amp;chksm=9bd34a28aca4c33e53fd8c0dda162eaedd491269721f305785c8f31730c0d7ddfb3d3f977f76&amp;scene=21#wechat_redirect" data-linktype="2"> <section data-recommend-title="t" style="width: 100%;background: rgb(245, 245, 245);display: flex;justify-content: center;align-items: center;flex-wrap: nowrap;padding: 6px 16px;font-size: 13px;font-weight: 400;color: rgb(68, 153, 231);line-height: 18px;" data-mid=""> <p style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width: 100%;" data-mid="">HTTP/3 来了 !HTTP/2 还没怎么用起来呢,先一起扫个盲吧!</p> </section></a> <a href="http://mp.weixin.qq.com/s?__biz=MzAxODcyNjEzNQ==&amp;mid=2247493346&amp;idx=2&amp;sn=b050ede0cf620bde815db76b85b53563&amp;chksm=9bd34b7aaca4c26cccf85503661d000b23911dc658123224ef2c65869f6984a61bc1a0eeb0bd&amp;scene=21#wechat_redirect" data-linktype="2"> <section data-recommend-title="t" style="width: 100%;display: flex;justify-content: center;align-items: center;flex-wrap: nowrap;padding: 6px 16px;font-size: 13px;font-weight: 400;color: rgb(68, 153, 231);line-height: 18px;" data-mid=""> <p style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width: 100%;" data-mid="">万字超强图文讲解 AQS 以及 ReentrantLock 应用</p> </section></a> <a href="http://mp.weixin.qq.com/s?__biz=MzAxODcyNjEzNQ==&amp;mid=2247493139&amp;idx=1&amp;sn=cc483b6de6d6b847046b6bd7ec9df293&amp;chksm=9bd34b8baca4c29d5f8620ad2d8e4c659838eb70604e63b8b69a777b46cd29cd9ded19d6338f&amp;scene=21#wechat_redirect" data-linktype="2"> <section data-recommend-title="t" style="width: 100%;background: rgb(245, 245, 245);display: flex;justify-content: center;align-items: center;flex-wrap: nowrap;padding: 6px 16px;font-size: 13px;font-weight: 400;color: rgb(68, 153, 231);line-height: 18px;border-bottom: none !important;" data-mid=""> <p style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width: 100%;" data-mid="">架构师究竟要不要写代码?</p> </section></a> </section> </section> </section> <p><br></p> <p data-lake-id="5c9baf15e0efacfc3b20b9e10f1a2048" style="font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;font-size: 14px;color: rgb(38, 38, 38);line-height: 1.74;letter-spacing: 0.05em;outline-style: none;"><span style="color: rgb(140, 140, 140);">前段时间组织过一波,关于面试内容的学习与讨论,效果还不错。有兄弟提议可以考虑把大家一起分享或者读到的干货内容都整理起来,除了我们自己查阅方便,可能也对其他人也会很有帮助。所以,我们决定一起弄个以「后端面试」为主题的公众号,平日主要推送一些面试中常见的技术点干货,以帮助大家学习和备战面试!</span></p> <p data-lake-id="5c9baf15e0efacfc3b20b9e10f1a2048" style="font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;font-size: 14px;color: rgb(38, 38, 38);line-height: 1.74;letter-spacing: 0.05em;outline-style: none;"><br></p> <p data-lake-id="407b930e0b9c9fc918db615186d1354c" style="font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;white-space: normal;background-color: rgb(255, 255, 255);text-align: center;font-size: 14px;color: rgb(38, 38, 38);line-height: 1.74;letter-spacing: 0.05em;outline-style: none;"><br></p> <p data-lake-id="a20d224c568e48b9d67847a2c66a8c01_p_0" style="font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;white-space: normal;background-color: rgb(255, 255, 255);text-align: center;font-size: 14px;color: rgb(38, 38, 38);line-height: 1.74;letter-spacing: 0.05em;outline-style: none;"><span style="color: rgb(140, 140, 140);">一起进大厂,每日学干货</span></p> <p data-lake-id="ded5728bff9ef6e898ffbfb4fc926bb3" style="font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;white-space: normal;background-color: rgb(255, 255, 255);text-align: center;font-size: 14px;color: rgb(38, 38, 38);line-height: 1.74;letter-spacing: 0.05em;outline-style: none;"><span style="color: rgb(140, 140, 140);">关注我,不迷路</span></p> <p data-lake-id="dbd203085b3600254742bf761bb84f43" style="font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;white-space: normal;background-color: rgb(255, 255, 255);text-align: center;font-size: 14px;color: rgb(38, 38, 38);line-height: 1.74;letter-spacing: 0.05em;outline-style: none;"><span data-card-type="inline" data-lake-card="image" data-card-value="data:%7B%22src%22%3A%22https%3A%2F%2Fcdn.nlark.com%2Fyuque%2F0%2F2020%2Fpng%2F244267%2F1591342850843-eb0c6963-2992-463f-af00-d681e7c091b7.png%22%2C%22originWidth%22%3A258%2C%22originHeight%22%3A258%2C%22size%22%3A0%2C%22display%22%3A%22inline%22%2C%22align%22%3A%22left%22%2C%22linkTarget%22%3A%22_blank%22%2C%22status%22%3A%22done%22%2C%22style%22%3A%22none%22%2C%22search%22%3A%22%22%2C%22margin%22%3A%7B%22top%22%3Afalse%2C%22bottom%22%3Afalse%7D%2C%22width%22%3A258%2C%22height%22%3A258%7D"><img data-ratio="1" data-type="png" data-w="258" src="/upload/7b57b8ce8a74c4aebec729d708bae61d.png" style="box-sizing: border-box !important;visibility: visible !important;width: 258px !important;"></span></p>

最新版redis 6.0.5安装

作者:じ☆ve不哭

# 安装redis #### 1.安装依赖 ``` yum install -y cpp binutils glibc glibc-kernheaders glibc-common glibc-devel gcc make tcl ``` #### 2.需要先安装gcc新版才能编译 centos7 默认的 gcc 版本小于 5.3 无法编译 ``` sudo yum -y install centos-release-scl sudo yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils // 临时生效,退出 shell 或重启会恢复原 gcc 版本 sudo scl enable devtoolset-9 bash // 永久生效 sudo echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile ``` #### 3.下载最新版本redis ``` wget http://download.redis.io/releases/redis-6.0.5.tar.gz ``` #### 4. 解压安装 ``` tar -zxvf redis-6.0.5.tar.gz cd redis-6.0.5 make make test make install ``` 编译文件会复制到/usr/local/bin目录下 #### 5.修改redis.conf文件并复制到etc目录 - bind 127.0.0.1 #根据情况是否需要远程访问去掉注释 - requirepass 123456 #修改密码 - protected-mode no # 关闭protected-mode模式,此时外部网络可以直接访问 ``` sudo mkdir /etc/redis sudo cp redis.conf /etc/redis/ ``` #### 6.在 /etc/systemd/system新建service文件 ``` sudo vi /etc/systemd/system/redis.service ``` 内容如下: ``` [Unit] Description=Redis After=network.target [Service] #Type=forking ExecStart=/usr/local/bin/redis-server /etc/redis/redis.conf ExecReload=/usr/local/bin/redis-server -s reload ExecStop=/usr/local/bin/redis-server -s stop PrivateTmp=true [Install] WantedBy=multi-user.target ``` **注意Type=forking不注释掉 服务无法启动** #### 7.安装systemd服务 ``` # 使服务自动运行 sudo systemctl daemon-reload sudo systemctl enable redis # 启动服务 sudo systemctl restart redis sudo systemctl status redis ```

API 面试四连杀:接口如何设计?安全如何保证?签名如何实现?防重如何实现?

作者:微信小助手

<p style="white-space: normal;text-align: center;" data-mpa-powered-by="yiban.io"><span style="font-size: 13px;color: rgb(136, 136, 136);font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;letter-spacing: 0.544px;">点击上方蓝色“</span><span style="font-size: 13px;font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;letter-spacing: 0.544px;color: rgb(0, 128, 255);">程序猿DD</span><span style="font-size: 13px;color: rgb(136, 136, 136);font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;letter-spacing: 0.544px;">”,选择“设为星标”</span><strong style="letter-spacing: 0.544px;color: rgb(74, 74, 74);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;font-size: 16px;white-space: pre-line;background-color: rgb(255, 255, 255);text-align: right;"></strong></p> <p style="white-space: normal;text-align: center;"><span style="font-size: 13px;"><span style="color: rgb(136, 136, 136);font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;letter-spacing: 0.544px;">回复“</span><span style="font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;letter-spacing: 0.544px;color: rgb(0, 128, 255);">资源</span><span style="color: rgb(136, 136, 136);font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;letter-spacing: 0.544px;">”获取独家整理的学习资料!</span></span></p> <p style="margin-top: 10px;margin-bottom: 10px;white-space: normal;text-align: center;"><span style="color: rgb(136, 136, 136);font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;font-size: 14px;letter-spacing: 0.544px;"><img data-backh="34" data-backw="540" data-ratio="0.0625" data-s="300,640" data-type="jpeg" data-w="640" width="100%" src="/upload/8c292e55ba5a23cb6ebc11f2a2c4fece.jpg" style="font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;box-sizing: border-box !important;visibility: visible !important;width: 654px !important;"><span style="color: rgb(178, 178, 178);font-family: Optima-Regular, PingFangTC-light;font-size: 13px;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);text-align: left;"></span></span></p> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com"> <h2 data-tool="mdnice编辑器" style="text-align: right;"><span style="font-size: 13px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;color: rgb(178, 178, 178);"><span style="color: rgb(178, 178, 178);font-size: 13px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;text-align: right;background-color: rgb(255, 255, 255);">来源&nbsp;|</span><span style="color: rgb(178, 178, 178);font-size: 13px;letter-spacing: 0.544px;text-align: right;background-color: rgb(255, 255, 255);font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;white-space: pre-line;">&nbsp;</span><span style="color: rgb(178, 178, 178);font-size: 13px;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;text-align: right;background-color: rgb(255, 255, 255);">cnblogs.com/jurendage/p/12653865.html</span></span></h2> <p data-tool="mdnice编辑器" style="padding-top: 1em;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;letter-spacing: 0.544px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(74, 74, 74);line-height: 1.75em;"><strong style="letter-spacing: 0.034em;line-height: 1.75em;">说明:在实际的业务中,难免会跟第三方系统进行数据的交互与传递,那么如何保证数据在传输过程中的安全呢(防窃取)?除了https的协议之外,能不能加上通用的一套算法以及规范来保证传输的安全性呢?</strong><br></p> <p data-tool="mdnice编辑器" style="padding-top: 1em;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;letter-spacing: 0.544px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(74, 74, 74);line-height: 1.75em;"><strong style="line-height: 1.75em;">下面我们就来讨论下常用的一些API设计的安全方法,可能不一定是最好的,有更牛逼的实现方式,但是这篇是我自己的经验分享.</strong></p> <h1 data-tool="mdnice编辑器" style="margin-top: 15px;text-align: center;"><span style="color: rgb(64, 118, 0);font-size: 20px;"><strong>一:token 简介</strong></span></h1> <p data-tool="mdnice编辑器" style="padding-top: 1em;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;letter-spacing: 0.544px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(74, 74, 74);line-height: 1.75em;">Token:访问令牌access token, 用于接口中, 用于标识接口调用者的身份、凭证,减少用户名和密码的传输次数。一般情况下客户端(接口调用方)需要先向服务器端申请一个接口调用的账号,服务器会给出一个appId和一个key, key用于参数签名使用,注意key保存到客户端,需要做一些安全处理,防止泄露。</p> <p data-tool="mdnice编辑器" style="padding-top: 1em;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;letter-spacing: 0.544px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(74, 74, 74);line-height: 1.75em;">Token的值一般是UUID,服务端生成Token后需要将token做为key,将一些和token关联的信息作为value保存到缓存服务器中(redis),当一个请求过来后,服务器就去缓存服务器中查询这个Token是否存在,存在则调用接口,不存在返回接口错误,一般通过拦截器或者过滤器来实现,Token分为两种:</p> <ul data-tool="mdnice编辑器" class="list-paddingleft-2" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;letter-spacing: 0.544px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);color: black;"> <li style="font-size: 14px;"> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <span style="font-size: 14px;">API Token(接口令牌): 用于访问不需要用户登录的接口,如登录、注册、一些基本数据的获取等。获取接口令牌需要拿appId、timestamp和sign来换,sign=加密(timestamp+key)</span> </section></li> <li style="font-size: 14px;"> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <span style="font-size: 14px;">USER Token(用户令牌): 用于访问需要用户登录之后的接口,如:获取我的基本信息、保存、修改、删除等操作。获取用户令牌需要拿用户名和密码来换</span> </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 1em;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;letter-spacing: 0.544px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(74, 74, 74);line-height: 1.75em;">关于Token的时效性:token可以是一次性的、也可以在一段时间范围内是有效的,具体使用哪种看业务需要。</p> <p data-tool="mdnice编辑器" style="padding-top: 1em;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;letter-spacing: 0.544px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(74, 74, 74);line-height: 1.75em;">一般情况下接口最好使用https协议,如果使用http协议,Token机制只是一种减少被黑的可能性,其实只能防君子不能防小人。</p> <p data-tool="mdnice编辑器" style="padding-top: 1em;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;letter-spacing: 0.544px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(74, 74, 74);line-height: 1.75em;">一般token、timestamp和sign 三个参数会在接口中会同时作为参数传递,每个参数都有各自的用途。</p> <h1 data-tool="mdnice编辑器" style="margin-top: 15px;text-align: center;"><span style="color: rgb(64, 118, 0);font-size: 20px;"><strong>二:timestamp 简介</strong></span></h1> <p data-tool="mdnice编辑器" style="padding-top: 1em;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;letter-spacing: 0.544px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(74, 74, 74);line-height: 1.75em;">timestamp: 时间戳,是客户端调用接口时对应的当前时间戳,时间戳用于防止DoS攻击。当黑客劫持了请求的url去DoS攻击,每次调用接口时接口都会判断服务器当前系统时间和接口中传的的timestamp的差值,如果这个差值超过某个设置的时间(假如5分钟),那么这个请求将被拦截掉,如果在设置的超时时间范围内,是不能阻止DoS攻击的。timestamp机制只能减轻DoS攻击的时间,缩短攻击时间。如果黑客修改了时间戳的值可通过sign签名机制来处理。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 1.2em;margin-bottom: 15px;font-weight: bold;font-size: 20px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.544px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);color: black;"><span style="margin-bottom: -1px;background-image: url(&quot;https://mmbiz.qpic.cn/mmbiz_png/JdLkEI9sZffFIA8hqzianBO5pa7C2IQvqrrK2Xy0Yes8FYFQea9pMl53uLqWZjWdibe4TvTVADnldZT8ErGFMDtg/640?wx_fmt=png&quot;);background-size: 100% 100%;background-repeat: no-repeat;display: inline-block;width: 16px;height: 15px;line-height: 15px;"></span><span style="margin-left: 8px;font-size: 17px;display: inline-block;color: rgb(72, 179, 120);">DoS</span></h3> <p data-tool="mdnice编辑器" style="padding-top: 1em;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;letter-spacing: 0.544px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(74, 74, 74);line-height: 1.75em;">DoS是Denial of Service的简称,即拒绝服务,造成DoS的攻击行为被称为DoS攻击,其目的是使计算机或网络无法提供正常的服务。最常见的DoS攻击有计算机网络带宽攻击和连通性攻击。</p> <p data-tool="mdnice编辑器" style="padding-top: 1em;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;letter-spacing: 0.544px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(74, 74, 74);line-height: 1.75em;">DoS攻击是指故意的攻击网络协议实现的缺陷或直接通过野蛮手段残忍地耗尽被攻击对象的资源,目的是让目标计算机或网络无法提供正常的服务或资源访问,使目标系统服务系统停止响应甚至崩溃,而在此攻击中并不包括侵入目标服务器或目标网络设备。这些服务资源包括网络带宽,文件系统空间容量,开放的进程或者允许的连接。这种攻击会导致资源的匮乏,无论计算机的处理速度多快、内存容量多大、网络带宽的速度多快都无法避免这种攻击带来的后果。</p> <ul data-tool="mdnice编辑器" class="list-paddingleft-2" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;letter-spacing: 0.544px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);color: black;"> <li style="font-size: 14px;"> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <span style="font-size: 14px;">Pingflood: 该攻击在短时间内向目的主机发送大量ping包,造成网络堵塞或主机资源耗尽。</span> </section></li> <li style="font-size: 14px;"> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <span style="font-size: 14px;">Synflood: 该攻击以多个随机的源主机地址向目的主机发送SYN包,而在收到目的主机的SYN ACK后并不回应,这样,目的主机就为这些源主机建立了大量的连接队列,而且由于没有收到ACK一直维护着这</span> </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 1em;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;letter-spacing: 0.544px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(74, 74, 74);line-height: 1.75em;">些队列,造成了资源的大量消耗而不能向正常请求提供服务。</p> <ul data-tool="mdnice编辑器" class="list-paddingleft-2" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;letter-spacing: 0.544px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);color: black;"> <li style="font-size: 14px;"> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <span style="font-size: 14px;">Smurf:该攻击向一个子网的广播地址发一个带有特定请求(如ICMP回应请求)的包,并且将源地址伪装成想要攻击的主机地址。子网上所有主机都回应广播包请求而向被攻击主机发包,使该主机受到攻击。</span> </section></li> <li style="font-size: 14px;"> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <span style="font-size: 14px;">Land-based:攻击者将一个包的源地址和目的地址都设置为目标主机的地址,然后将该包通过IP欺骗的方式发送给被攻击主机,这种包可以造成被攻击主机因试图与自己建立连接而陷入死循环,从而很大程度地降低了系统性能。</span> </section></li> <li style="font-size: 14px;"> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <span style="font-size: 14px;">Ping of Death:根据TCP/IP的规范,一个包的长度最大为65536字节。尽管一个包的长度不能超过65536字节,但是一个包分成的多个片段的叠加却能做到。当一个主机收到了长度大于65536字节的包时,就是受到了Ping of Death攻击,该攻击会造成主机的宕机。</span> </section></li> <li style="font-size: 14px;"> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <span style="font-size: 14px;">Teardrop:IP数据包在网络传递时,数据包可以分成更小的片段。攻击者可以通过发送两段(或者更多)数据包来实现TearDrop攻击。第一个包的偏移量为0,长度为N,第二个包的偏移量小于N。为了合并这些数据段,TCP/IP堆栈会分配超乎寻常的巨大资源,从而造成系统资源的缺乏甚至机器的重新启动。</span> </section></li> <li style="font-size: 14px;"> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <span style="font-size: 14px;">PingSweep:使用ICMP Echo轮询多个主机。</span> </section></li> </ul> <h1 data-tool="mdnice编辑器" style="text-align: center;margin-top: 25px;"><span style="font-size: 20px;"><strong><span style="font-size: 20px;color: rgb(64, 118, 0);">三:sign 简介</span></strong></span></h1> <p data-tool="mdnice编辑器" style="padding-top: 1em;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;letter-spacing: 0.544px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(74, 74, 74);line-height: 1.75em;">nonce:随机值,是客户端随机生成的值,作为参数传递过来,随机值的目的是增加sign签名的多变性。随机值一般是数字和字母的组合,6位长度,随机值的组成和长度没有固定规则。</p> <p data-tool="mdnice编辑器" style="padding-top: 1em;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 16px;letter-spacing: 0.544px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(74, 74, 74);line-height: 1.75em;">sign: 一般用于参数签名,防止参数被非法篡改,最常见的是修改金额等重要敏感参数, sign的值一般是将所有非空参数按照升续排序然后+token+key+timestamp+nonce(随机数)拼接在一起,然后使用某种加密算法进行加密,作为接口中的一个参数sign来传递,也可以将sign放到请求头中。接口在网络传输过程中如果被黑客挟持,并修改其中的参数值,然后再继续调用接口,虽然参数的值被修改了,但是因为黑客不知道sign是如何计算出来的,不知道sign都有哪些值构成,不知道以怎样的顺序拼接在一起的,最重要的是不知道签名字符串中的key是什么,所以黑客可以篡改参数的值,但没法修改sign的值,当服务器调用接口前会按照sign的规则重新计算出sign的值然后和接口传递的sign参数的值做比较,如果相等表示参数值没有被篡改,如果不等,表示参数被非法篡改了,就不执行接口了。</p> <h1 data-tool="mdnice编辑器" style="text-align: center;margin-top: 15px;"><span style="font-size: 20px;"><strong><span style="font-size: 20px;color: