文章列表

SpringBoot 项目打成 .exe 程序,实战来了,超级详细!

作者:微信小助手

<section data-mpa-powered-by="yiban.io"> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-weui-theme="light" data-id="MzA5MTU0OTY0Ng==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/zc3KLDBfJlmPt0J5PXYOoiaG8wsQPZrLevbxMZSfgQ0YypNYaicnbS0P9UicluuOySLSP4CjTcRUVHCZzYeXQ9WlA/0?wx_fmt=png" data-nickname="Java派" data-alias="javapai" data-signature="专注Java相关技术栈:Spring全家筒、Docker、k8s、Mysql、集群、微服务、中间件等知识。" data-from="0" data-is_biz_ban="0"></mp-common-profile> </section> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="font-size: 16px;color: black;padding-right: 10px;padding-left: 10px;line-height: 1.6;letter-spacing: 0px;word-break: break-word;overflow-wrap: break-word;text-align: left;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;margin-bottom: 0px;"> <section style="outline: 0px;font-size: 15px;color: rgb(34, 34, 34);font-family: system-ui, -apple-system, 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);visibility: visible;"> <span style="color: rgb(89, 89, 89);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: 0px;">近期做了一个前后端合并的spring boot项目,但是要求达成exe文件,提供给不懂电脑的小白安装使用,就去研究了半天,踩了很多坑,写这篇文章,是想看到这篇文章的人,按照我的步骤走,能少踩坑。</span> <br> </section> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;font-weight: bold;font-size: 22px;border-bottom: 2px solid rgb(89, 89, 89);margin-bottom: 30px;color: rgb(89, 89, 89);"><span style="display: none;"></span><span style="display: inline-block;border-bottom: 2px solid rgb(89, 89, 89);">准备</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">准备工作:</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">1.一个jar包,没有bug能正常启动的jar包</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">2.exe4j,一个将jar转换成exe的工具</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <strong style="color: rgb(71, 193, 168);">链接</strong>:https://pan.baidu.com/s/1gt6wen7BKto8esE70XnxwQ </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <strong style="color: rgb(71, 193, 168);">提取码:</strong>vhoy </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <strong style="color: rgb(71, 193, 168);">注册码:</strong>L-g782dn2d-1f1yqxx1rv1sqd </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">3.inno setup,一个将依赖和exe一起打成一个安装程序的工具</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <strong style="color: rgb(71, 193, 168);">链接</strong>:https://pan.baidu.com/s/12KjHSpcth1LXhcggc11_VA </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <strong style="color: rgb(71, 193, 168);">提取码</strong>:wphi </section></li> </ul> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;font-weight: bold;font-size: 22px;border-bottom: 2px solid rgb(89, 89, 89);margin-bottom: 30px;color: rgb(89, 89, 89);"><span style="display: none;"></span><span style="display: inline-block;border-bottom: 2px solid rgb(89, 89, 89);">开始</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">以我为例子,我将jar包放在了桌面</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.9236641221374046" src="/upload/be04080c8f775c2ccbfc3a41684b813c.png" data-type="png" data-w="131" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">打开安装好的exe4j</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7644787644787645" src="/upload/cada5ada85dbaf2cd413bd180a263e.png" data-type="png" data-w="1036" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">直接下一步进入界面,选择JAVA转EXE</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7641963426371511" src="/upload/dd4793aee523112d8a4e71718beaf1e7.png" data-type="png" data-w="1039" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">然后点下一步,输入名称和输出路径</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7690086621751684" src="/upload/14cfc67c1a22fecb9eac3fbb5d0e9caa.png" data-type="png" data-w="1039" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">继续点击下一步,选择启动模式</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.770048309178744" src="/upload/84629009654e9944e7e556d205254483.png" data-type="png" data-w="1035" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">下方有个选项,需要设置打包后的程序兼容32和64位系统</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7736030828516378" src="/upload/c393c13ac6e16e9b5d79c64b31b1b7fe.png" data-type="png" data-w="1038" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">进来后勾选上</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.763915547024952" src="/upload/7d4f0cef26f7174a02dbc3c186b29fd0.png" data-type="png" data-w="1042" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">然后一直下一步,一直出现如下界面,开始选择jar包以及配置</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">在VM参数配置的地方加上:-Dfile.encoding=utf-8</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7660594439117929" src="/upload/1e9cbcb7c3ddf0b5fa774e05d2c9d79b.png" data-type="png" data-w="1043" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7615384615384615" src="/upload/46f063ecc59c454cbf0e0985dce6d1c3.png" data-type="png" data-w="1040" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7632575757575758" src="/upload/6dafd1cc912c904cde9a06c591f54ab0.png" data-type="png" data-w="1056" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7689357622243528" src="/upload/371ad1d2dbe1bc3aa63d09b46e802376.png" data-type="png" data-w="1043" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">点击下一步,配置JRE</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7605363984674329" src="/upload/d11f6cccc411aeecd00684636c7f684.png" data-type="png" data-w="1044" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">下拉框点击后进入如下界面</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7612655800575263" src="/upload/d4242d2e2a10a4421d7eeb99379f0bee.png" data-type="png" data-w="1043" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.5459016393442623" src="/upload/ee1e203eecaf82cc992c379f3428e30.png" data-type="png" data-w="610" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">照着这个样子写的目的是,最终会把本地jre目录和exe一起打包,让exe文件自己去根据路径去查找一起打包的jre,可不用再安装jdk</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7651006711409396" src="/upload/4c77feb553e090b396f3897229cf1595.png" data-type="png" data-w="1043" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">接着下一步,选择Client VM</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7672413793103449" src="/upload/cd55defa281541d39afbe7cbbd5d86a3.png" data-type="png" data-w="1044" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">然后一直下一步,最终出现如下界面</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7675312199807877" src="/upload/f545c0137779412564e03ffb2728796b.png" data-type="png" data-w="1041" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">这个时候你会发现桌面多了一个demo.exe文件,这个时候先别着急点开,接下来就是将jre和exe文件再打个包合并,达到在没有jdk电脑环境下也能运行</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">打开inno setup,左上角File - New</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7731629392971247" src="/upload/c9be30fac6d6b19488200889d91c938e.png" data-type="png" data-w="626" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">直接点下一步,填写配置,应用名称,版本等,随意</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7731629392971247" src="/upload/23ba6242c1f8bcfe2e1d59069bae48e1.png" data-type="png" data-w="626" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">然后点击下一步,这个地方默认就行,直接下一步</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7731629392971247" src="/upload/43a47faee7522db51d9437f0b98b74c3.png" data-type="png" data-w="626" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">接着选择生成好的exe文件</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7731629392971247" src="/upload/5392b2a4beb95171419ebeb30935ca7e.png" data-type="png" data-w="626" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">然后下一步,进入这个界面保持默认,直接下一步</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7731629392971247" src="/upload/5dd6e3d4adc955a38ec65f194bf1dd81.png" data-type="png" data-w="626" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">依旧下一步,不用管</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7731629392971247" src="/upload/19d0462519828a7e6dc9a944e4416aac.png" data-type="png" data-w="626" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">继续下一步,这里是选择语言</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7731629392971247" src="/upload/16aa0be09198a0c6dd2be9115b960e61.png" data-type="png" data-w="626" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">然后就是选择输出路径和填写安装程序的名字了</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7731629392971247" src="/upload/faa1477b56a2ca14d86e4fc0afbbd400.png" data-type="png" data-w="626" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">然后下一步,直接点Next,然后结束</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">配置到最后一步了,脚本文件,到这里会弹出问你是否马上编译,选择否,先把脚本写好再自己编译</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.6224" src="/upload/e04710524fbe186ab2559f95c6bea5c1.png" data-type="png" data-w="1250" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">然后到了最后一步了,把本地的JRE写进脚本</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.28169014084507044" src="/upload/fa021d6ff90b95a021e54ce0a06177ea.png" data-type="png" data-w="639" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.31616341030195383" src="/upload/c2ac1048f7d2cc5b510d59288d5d5b5d.png" data-type="png" data-w="563" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.11688311688311688" src="/upload/d846f0c8018801803c36afa991c12d85.png" data-type="png" data-w="1078" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.22674017918676775" src="/upload/5407b4805bff7cd9f68904e1acafd274.png" data-type="png" data-w="1451" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);"><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(71, 193, 168);">Source: "自己本地JRE路径\*"; DestDir: "{app}\{#MyJreName}"; Flags: ignoreversion recursesubdirs createallsubdirs</code></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">然后直接编译就好了,会提示保存当前脚本,随便起个名字,下个还可以继续用</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.42470389170896783" src="/upload/813499190b8df5a8e1781b3cf8867d17.png" data-type="png" data-w="591" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">然后等待绿色滚动条结束</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.37858220211161386" src="/upload/679fe8556daf13219f00bfb410c4f062.png" data-type="png" data-w="663" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">当绿色滚动条结束后,桌面会多了一个setup.exe文件</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.8770491803278688" src="/upload/85bd0e362613931da9ec45da7b915b1d.png" data-type="png" data-w="122" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">也同时会跳出一个安装的,因为程序帮你自动启动生成的安装程序了,安装就可以了,安装的时候记得勾选创建快捷方式</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="1.0576923076923077" src="/upload/9ce875ff54acb086a6ac3da44c60af34.png" data-type="png" data-w="104" style="display: block;margin-right: auto;margin-left: auto;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);">这个就是最后的程序了,双击运行就可以看到结果了,把setup.exe文件给别人安装,就都可以看到自己的程序了</p> </section>

MyBatis Plus 解决大数据量查询慢问题

作者:微信小助手

<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="font-size: 16px;color: black;padding-right: 10px;padding-left: 10px;line-height: 1.6;letter-spacing: 0px;word-break: break-word;text-align: left;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;" data-mpa-powered-by="yiban.io"> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">大数据量操作的场景大致如下:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> 数据迁移 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> 数据导出 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> 批量处理数据 </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">在实际工作中当指定查询数据过大时,我们一般使用分页查询的方式一页一页的将数据放到内存处理。但有些情况不需要分页的方式查询数据或分很大一页查询数据时,如果一下子将数据全部加载出来到内存中,很可能会发生OOM(内存溢出);而且查询会很慢,因为框架耗费大量的时间和内存去把数据库查询的结果封装成我们想要的对象(实体类)。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;"><strong>举例:在业务系统需要从 MySQL 数据库里读取 100w 数据行进行处理,应该怎么做?</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">做法通常如下:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> <strong style="color: black;">常规查询:</strong> 一次性读取 100w 数据到 JVM 内存中,或者分页读取 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> <strong style="color: black;">流式查询:</strong> 建立长连接,利用服务端游标,每次读取一条加载到 JVM 内存(多次获取,一次一行) </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> <strong style="color: black;">游标查询:</strong> 和流式一样,通过 fetchSize 参数,控制一次读取多少条数据(多次获取,一次多行) </section></li> </ul> <h2 data-tool="mdnice编辑器" style="font-weight: bold;font-size: 22px;margin: 10px auto;height: 40px;background-color: rgb(251, 251, 251);border-bottom: 1px solid rgb(246, 246, 246);overflow: hidden;"><span style="display: none;"></span><span style="margin-left: -10px;display: inline-block;width: auto;height: 40px;background-color: rgb(33, 33, 34);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 30px;padding-left: 30px;line-height: 40px;font-size: 16px;">常规查询</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">默认情况下,完整的检索结果集会将其存储在内存中。在大多数情况下,这是最有效的操作方式,并且由于 MySQL 网络协议的设计,因此更易于实现。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">举例:</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">假设单表 100w 数据量,一般会采用分页的方式查询:</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="display: block;background: url(&quot;https://mmbiz.qpic.cn/mmbiz_svg/wJibWkqN1bUMGV1UTPd8Fdpk5DkwOALK5OicnGYbUibolmjRSZszGZUY7QHBLgDNDCK13MVWicLDtDvpFzcA1Fvejxv7BCicI4UZ3/640?wx_fmt=svg&quot;) 10px 10px / 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #282c34;border-radius: 5px;"><span style="color: #61aeee;line-height: 26px;">@Mapper</span><br><span style="color: #c678dd;line-height: 26px;">public</span>&nbsp;<span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;">interface</span>&nbsp;<span style="color: #e6c07b;line-height: 26px;">BigDataSearchMapper</span>&nbsp;<span style="color: #c678dd;line-height: 26px;">extends</span>&nbsp;<span style="color: #e6c07b;line-height: 26px;">BaseMapper</span>&lt;<span style="color: #e6c07b;line-height: 26px;">BigDataSearchEntity</span>&gt;&nbsp;</span>{<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #61aeee;line-height: 26px;">@Select</span>(<span style="color: #98c379;line-height: 26px;">"SELECT&nbsp;bds.*&nbsp;FROM&nbsp;big_data_search&nbsp;bds&nbsp;${ew.customSqlSegment}&nbsp;"</span>)<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 26px;">Page&lt;BigDataSearchEntity&gt;&nbsp;<span style="color: #61aeee;line-height: 26px;">pageList</span><span style="line-height: 26px;">(@Param(<span style="color: #98c379;line-height: 26px;">"page"</span>)</span>&nbsp;Page&lt;BigDataSearchEntity&gt;&nbsp;page,&nbsp;@<span style="color: #61aeee;line-height: 26px;">Param</span><span style="line-height: 26px;">(Constants.WRAPPER)</span>&nbsp;QueryWrapper&lt;BigDataSearchEntity&gt;&nbsp;queryWrapper)</span>;<br>&nbsp;<br>}<br></code></pre> <blockquote data-tool="mdnice编辑器" style="border-top: none;border-right: none;border-bottom: none;font-size: 0.9em;overflow: auto;background: rgba(0, 0, 0, 0.05);padding: 10px 1em;border-left-color: rgb(221, 221, 221);margin-top: 1.2em;margin-bottom: 1.2em;border-left-width: 4px;color: rgb(119, 119, 119);quotes: none;"> <p style="padding-top: 8px;padding-bottom: 8px;white-space: normal;text-size-adjust: auto;font-size: 15px;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;line-height: 1.75em;">注:该示例使用的 MybatisPlus</p> </blockquote> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">该方式比较简单,如果在不考虑 LIMIT 深分页优化情况下,估计你的数据库服务器就噶皮了,或者你能等上几十分钟或几小时,甚至几天时间检索数据</p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;font-size: 22px;margin: 10px auto;height: 40px;background-color: rgb(251, 251, 251);border-bottom: 1px solid rgb(246, 246, 246);overflow: hidden;"><span style="display: none;"></span><span style="margin-left: -10px;display: inline-block;width: auto;height: 40px;background-color: rgb(33, 33, 34);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 30px;padding-left: 30px;line-height: 40px;font-size: 16px;">流式查询</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">流式查询指的是查询成功后不是返回一个集合而是返回一个迭代器,应用每次从迭代器取一条查询结果。流式查询的好处是能够降低内存使用。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">如果没有流式查询,我们想要从数据库取 100w 条记录而又没有足够的内存时,就不得不分页查询,而分页查询效率取决于表设计,如果设计的不好,就无法执行高效的分页查询。因此流式查询是一个数据库访问框架必须具备的功能。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">MyBatis 中使用流式查询避免数据量过大导致 OOM ,但在流式查询的过程当中,数据库连接是保持打开状态的,因此要注意的是:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> 执行一个流式查询后,数据库访问框架就不负责关闭数据库连接了,需要应用在取完数据后自己关闭。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> 必须先读取(或关闭)结果集中的所有行,然后才能对连接发出任何其他查询,否则将引发异常。 </section></li> </ul> <h5 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;"><span style="display: none;"></span>MyBatis 流式查询接口<span style="display: none;"></span></h5> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">MyBatis 提供了一个叫 <code style="font-size: 14px;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);">org.apache.ibatis.cursor.Cursor</code> 的接口类用于流式查询,这个接口继承了 <code style="font-size: 14px;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);">java.io.Closeable</code> 和 <code style="font-size: 14px;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);">java.lang.Iterable</code> 接口,由此可知:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> Cursor 是可关闭的; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> Cursor 是可遍历的。 </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">除此之外,Cursor 还提供了三个方法:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> <strong style="color: black;">isOpen():</strong> 用于在取数据之前判断 Cursor 对象是否是打开状态。只有当打开时 Cursor 才能取数据; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> <strong style="color: black;">isConsumed():</strong> 用于判断查询结果是否全部取完。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> <strong style="color: black;">getCurrentIndex():</strong> 返回已经获取了多少条数据 </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">使用流式查询,则要保持对产生结果集的语句所引用的表的并发访问,因为其 查询会独占连接,所以必须尽快处理</p> <h5 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;"><span style="display: none;"></span>为什么要用流式查询?<span style="display: none;"></span></h5> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">如果有一个很大的查询结果需要遍历处理,又不想一次性将结果集装入客户端内存,就可以考虑使用流式查询;</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">分库分表场景下,单个表的查询结果集虽然不大,但如果某个查询跨了多个库多个表,又要做结果集的合并、排序等动作,依然有可能撑爆内存;详细研究了<code style="font-size: 14px;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);">sharding-sphere</code>的代码不难发现,除了<code style="font-size: 14px;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);">group by</code>与<code style="font-size: 14px;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);">order by</code>字段不一样之外,其他的场景都非常适合使用流式查询,可以最大限度的降低对客户端内存的消耗。</p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;font-size: 22px;margin: 10px auto;height: 40px;background-color: rgb(251, 251, 251);border-bottom: 1px solid rgb(246, 246, 246);overflow: hidden;"><span style="display: none;"></span><span style="margin-left: -10px;display: inline-block;width: auto;height: 40px;background-color: rgb(33, 33, 34);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 30px;padding-left: 30px;line-height: 40px;font-size: 16px;">游标查询</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">对大量数据进行处理时,为防止内存泄漏情况发生,也可以采用游标方式进行数据查询处理。这种处理方式比常规查询要快很多。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">当查询百万级的数据的时候,还可以使用游标方式进行数据查询处理,不仅可以节省内存的消耗,而且还不需要一次性取出所有数据,可以进行逐条处理或逐条取出部分批量处理。一次查询指定 <code style="font-size: 14px;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);">fetchSize</code> 的数据,直到把数据全部处理完。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">Mybatis 的处理加了两个注解:<code style="font-size: 14px;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);">@Options</code> 和 <code style="font-size: 14px;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);">@ResultType</code></p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="display: block;background: url(&quot;https://mmbiz.qpic.cn/mmbiz_svg/wJibWkqN1bUMGV1UTPd8Fdpk5DkwOALK5OicnGYbUibolmjRSZszGZUY7QHBLgDNDCK13MVWicLDtDvpFzcA1Fvejxv7BCicI4UZ3/640?wx_fmt=svg&quot;) 10px 10px / 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #282c34;border-radius: 5px;"><span style="color: #61aeee;line-height: 26px;">@Mapper</span><br><span style="color: #c678dd;line-height: 26px;">public</span>&nbsp;<span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;">interface</span>&nbsp;<span style="color: #e6c07b;line-height: 26px;">BigDataSearchMapper</span>&nbsp;<span style="color: #c678dd;line-height: 26px;">extends</span>&nbsp;<span style="color: #e6c07b;line-height: 26px;">BaseMapper</span>&lt;<span style="color: #e6c07b;line-height: 26px;">BigDataSearchEntity</span>&gt;&nbsp;</span>{<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #5c6370;font-style: italic;line-height: 26px;">//&nbsp;方式一&nbsp;多次获取,一次多行</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #61aeee;line-height: 26px;">@Select</span>(<span style="color: #98c379;line-height: 26px;">"SELECT&nbsp;bds.*&nbsp;FROM&nbsp;big_data_search&nbsp;bds&nbsp;${ew.customSqlSegment}&nbsp;"</span>)<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #61aeee;line-height: 26px;">@Options</span>(resultSetType&nbsp;=&nbsp;ResultSetType.FORWARD_ONLY,&nbsp;fetchSize&nbsp;=&nbsp;<span style="color: #d19a66;line-height: 26px;">1000000</span>)<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="line-height: 26px;">Page&lt;BigDataSearchEntity&gt;&nbsp;<span style="color: #61aeee;line-height: 26px;">pageList</span><span style="line-height: 26px;">(@Param(<span style="color: #98c379;line-height: 26px;">"page"</span>)</span>&nbsp;Page&lt;BigDataSearchEntity&gt;&nbsp;page,&nbsp;@<span style="color: #61aeee;line-height: 26px;">Param</span><span style="line-height: 26px;">(Constants.WRAPPER)</span>&nbsp;QueryWrapper&lt;BigDataSearchEntity&gt;&nbsp;queryWrapper)</span>;<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #5c6370;font-style: italic;line-height: 26px;">//&nbsp;方式二&nbsp;一次获取,一次一行</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #61aeee;line-height: 26px;">@Select</span>(<span style="color: #98c379;line-height: 26px;">"SELECT&nbsp;bds.*&nbsp;FROM&nbsp;big_data_search&nbsp;bds&nbsp;${ew.customSqlSegment}&nbsp;"</span>)<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #61aeee;line-height: 26px;">@Options</span>(resultSetType&nbsp;=&nbsp;ResultSetType.FORWARD_ONLY,&nbsp;fetchSize&nbsp;=&nbsp;<span style="color: #d19a66;line-height: 26px;">100000</span>)<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #61aeee;line-height: 26px;">@ResultType</span>(BigDataSearchEntity<span style="line-height: 26px;">.<span style="color: #c678dd;line-height: 26px;">class</span>)<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #e6c07b;line-height: 26px;">void</span>&nbsp;<span style="color: #e6c07b;line-height: 26px;">listData</span>(@<span style="color: #e6c07b;line-height: 26px;">Param</span>(<span style="color: #e6c07b;line-height: 26px;">Constants</span>.<span style="color: #e6c07b;line-height: 26px;">WRAPPER</span>)&nbsp;<span style="color: #e6c07b;line-height: 26px;">QueryWrapper</span>&lt;<span style="color: #e6c07b;line-height: 26px;">BigDataSearchEntity</span>&gt;&nbsp;<span style="color: #e6c07b;line-height: 26px;">queryWrapper</span>,&nbsp;<span style="color: #e6c07b;line-height: 26px;">ResultHandler</span>&lt;<span style="color: #e6c07b;line-height: 26px;">BigDataSearchEntity</span>&gt;&nbsp;<span style="color: #e6c07b;line-height: 26px;">handler</span>)</span>;<br>&nbsp;<br>}<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;"><strong>@Options</strong></p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> <code style="font-size: 14px;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);">ResultSet.FORWORD_ONLY</code>:结果集的游标只能向下滚动 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> <code style="font-size: 14px;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);">ResultSet.SCROLL_INSENSITIVE</code>:结果集的游标可以上下移动,当数据库变化时,当前结果集不变 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> <code style="font-size: 14px;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);">ResultSet.SCROLL_SENSITIVE</code>:返回可滚动的结果集,当数据库变化时,当前结果集同步改变 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> <code style="font-size: 14px;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);">fetchSize</code>:每次获取量 </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;"><strong>@ResultType</strong></p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> <code style="font-size: 14px;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);">@ResultType(BigDataSearchEntity.class)</code>:转换成返回实体类型 </section></li> </ul> <blockquote data-tool="mdnice编辑器" style="border-top: none;border-right: none;border-bottom: none;font-size: 0.9em;overflow: auto;background: rgba(0, 0, 0, 0.05);padding: 10px 1em;border-left-color: rgb(221, 221, 221);margin-top: 1.2em;margin-bottom: 1.2em;border-left-width: 4px;color: rgb(119, 119, 119);quotes: none;"> <p style="padding-top: 8px;padding-bottom: 8px;white-space: normal;text-size-adjust: auto;font-size: 15px;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;line-height: 1.75em;">注意:返回类型必须为 void ,因为查询的结果在 <code style="font-size: 14px;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);">ResultHandler</code> 里处理数据,所以这个 hander 也是必须的,可以使用 lambda 实现一个依次处理逻辑。</p> </blockquote> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;"><strong>注意:</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">虽然上面的代码中都有 <code style="font-size: 14px;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);">@Options</code> 但实际操作却有不同:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> 方式一是多次查询,一次返回多条; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> 方式二是一次查询,一次返回一条; </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;"><strong>原因:</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">Oracle 是从服务器一次取出 <code style="font-size: 14px;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);">fetch size</code> 条记录放在客户端,客户端处理完成一个批次后再向服务器取下一个批次,直到所有数据处理完成。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">MySQL 是在执行 <code style="font-size: 14px;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);">ResultSet.next()</code> 方法时,会通过数据库连接一条一条的返回。<code style="font-size: 14px;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);">flush buffer</code> 的过程是阻塞式的,如果网络中发生了拥塞,<code style="font-size: 14px;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);">send buffer</code> 被填满,会导致 buffer 一直 flush 不出去,那 MySQL 的处理线程会阻塞,从而避免数据把客户端内存撑爆。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;"><strong>非流式查询和流式查询区别:</strong></p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> 非流式查询:内存会随着查询记录的增长而近乎直线增长。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);font-size: 15px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;"> 流式查询:内存会保持稳定,不会随着记录的增长而增长。其内存大小取决于批处理大小 <code style="font-size: 14px;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);">BATCH_SIZE</code>的设置,该尺寸越大,内存会越大。所以BATCH_SIZE应该根据业务情况设置合适的大小。 </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;margin-bottom: 16px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Segoe UI&quot;, Arial, freesans, sans-serif;font-size: 15px;white-space: normal;text-size-adjust: auto;line-height: 1.75em;">另外要切记每次处理完一批结果要记得释放存储每批数据的临时容器,即上文中的<code style="font-size: 14px;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);">gxids.clear()</code>;</p> </section> <pre style="outline: 0px;letter-spacing: 0.544px;color: rgb(62, 62, 62);font-size: 16px;background-color: rgb(255, 255, 255);"> <blockquote data-type="2" data-url="" data-author-name="" data-content-utf8-length="63" data-source-title="" data-text="原文链接:zhihu.com/question/551451538/answer/2667817410作者:invalid s" data-editid="1yh2jbpro21u3139j4" style="outline: 0px;color: rgba(0, 0, 0, 0.5);letter-spacing: 0.544px;white-space: normal;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;text-align: left;"> <section style="outline: 0px;"> <section style="outline: 0px;"> <span style="outline: 0px;font-size: 12px;font-family: system-ui, -apple-system, 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;">来源:blog.csdn.net/xhaimail/article/details/119386460</span> </section> </section> </blockquote></pre>

MySQL数据同步ES的4种方法!你能想到几种?

作者:微信小助手

<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="padding-right: 10px;padding-left: 10px;text-align: left;line-height: 1.6;letter-spacing: 0.034em;color: rgb(63, 63, 63);font-size: 16px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;" data-mpa-powered-by="yiban.io"> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">大家好,我是老三,这期给大家分享一个电商中常见的场景——MySQL数据同步Elasticsearch。</p> <section> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-weui-theme="light" data-id="MzkwODE5ODM0Ng==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/PMZOEonJxWdFLJg0sAOqwHB1mb24icMADUgxm1qZQft5aN3H37NAmQnOvpGB7J9JVHxC6NSiacxbBP1DYdhIAeyA/0?wx_fmt=png" data-nickname="三分恶" data-alias="Fighter3FullStack" data-signature="CSDN博客专家、优质创作者,华为云云享专家;肝过外包、混过国企,目前在一家跨境电商搬砖;写过诗,打过拳,佛系小码农。认真讲技术,随性侃人生,关注我,我们一起走的更远。" data-from="0" data-is_biz_ban="0"></mp-common-profile> </section> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="2.1706484641638224" src="/upload/379a779f07d0af473dfb0f931ae8fc5c.png" data-type="png" data-w="586" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> <figcaption style="margin-top: 5px;text-align: center;color: rgb(136, 136, 136);font-size: 12px;font-family: PingFangSC-Light;"> 商品检索 </figcaption> </figure> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">大家应该都在各种电商网站检索过商品,检索商品一般都是通过什么实现呢?搜索引擎Elasticsearch。</p> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">那么问题来了,商品上架,数据一般写入到MySQL的数据库中,那么用于检索的数据又是怎么同步到Elasticsearch的呢?</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.3123425692695214" src="/upload/b392c8a7105226bde63a663fca6f75dc.png" data-type="png" data-w="794" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> <figcaption style="margin-top: 5px;text-align: center;color: rgb(136, 136, 136);font-size: 12px;font-family: PingFangSC-Light;"> MySQL同步ES </figcaption> </figure> <h1 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 24px;text-align: center;background-image: url(&quot;https://mmbiz.qpic.cn/mmbiz_png/PMZOEonJxWdEy0ZPFSJ5Z68A23ZKOicMuxTxueyul32mFDaW01wBlfpniayURRWu1mlq1YTf0vEUBdKrtr2SUQWw/640?wx_fmt=png&quot;);background-position: center top;background-repeat: no-repeat;background-size: 75px;line-height: 95px;margin-top: 38px;margin-bottom: 10px;"><span style="font-size: 20px;color: #48b378;border-bottom: 2px solid #2e7950;">1.同步双写</span></h1> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">这是能想到的最直接的方式,在写入MySQL,直接也同步往ES里写一份数据。</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.8571428571428571" src="/upload/2ac879166195e60d3433244cf74e45ed.png" data-type="png" data-w="756" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> <figcaption style="margin-top: 5px;text-align: center;color: rgb(136, 136, 136);font-size: 12px;font-family: PingFangSC-Light;"> 同步双写 </figcaption> </figure> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">对于这种方式:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 优点:实现简单 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 缺点: </section></li> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;list-style-type: square;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 业务耦合,商品的管理中耦合大量数据同步代码 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 影响性能,写入两个存储,响应时间变长 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 不便扩展:搜索可能有一些个性化需求,需要对数据进行聚合,这种方式不便实现 </section></li> </ul> </ul> <h1 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 24px;text-align: center;background-image: url(&quot;https://mmbiz.qpic.cn/mmbiz_png/PMZOEonJxWdEy0ZPFSJ5Z68A23ZKOicMuxTxueyul32mFDaW01wBlfpniayURRWu1mlq1YTf0vEUBdKrtr2SUQWw/640?wx_fmt=png&quot;);background-position: center top;background-repeat: no-repeat;background-size: 75px;line-height: 95px;margin-top: 38px;margin-bottom: 10px;"><span style="font-size: 20px;color: #48b378;border-bottom: 2px solid #2e7950;">2.异步双写</span></h1> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">我们也很容易想到异步双写的办法,上架商品的时候,先把商品数据丢进MQ,为了解耦合,我们一般会拆分一个搜索服务,由搜索服务去订阅商品变动的消息,来完成同步。</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.6485943775100401" src="/upload/b38434de64f5c03468dcf30315188971.png" data-type="png" data-w="996" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> <figcaption style="margin-top: 5px;text-align: center;color: rgb(136, 136, 136);font-size: 12px;font-family: PingFangSC-Light;"> 异步双写 </figcaption> </figure> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">前面说的,一些数据需要聚合处理成类似宽表的结构怎么办呢?例如商品库的商品品类、spu、sku表是分开的,但是查询是跨维度的,在ES里再聚合一次效率就低一些,最好就是把商品的数据给聚合起来,在ES里以类似大宽表的形式存储,这样一来查询效率就高一些。</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="1.0574324324324325" src="/upload/2323c0644f9643150602650d239c026e.png" data-type="png" data-w="1184" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> <figcaption style="margin-top: 5px;text-align: center;color: rgb(136, 136, 136);font-size: 12px;font-family: PingFangSC-Light;"> 多维度多条件查询 </figcaption> </figure> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">这种其实没什么好办法,基本上还是得搜索服务直接查库,或者远程调用,再查询一遍商品的数据库,就是所谓的回查。</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.6102003642987249" src="/upload/8b6ba55fcf2e97e56356cc6426f129cc.png" data-type="png" data-w="1098" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> <figcaption style="margin-top: 5px;text-align: center;color: rgb(136, 136, 136);font-size: 12px;font-family: PingFangSC-Light;"> 回查完成聚合 </figcaption> </figure> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">这种方式:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 优点: </section></li> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;list-style-type: square;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 解耦合,商品服务无需关注数据同步 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 实时性较好,使用MQ,正常情况下,同步完成在秒级 </section></li> </ul> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 缺点: </section></li> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;list-style-type: square;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 引入了新的组件和服务,增加了复杂度 </section></li> </ul> </ul> <h1 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 24px;text-align: center;background-image: url(&quot;https://mmbiz.qpic.cn/mmbiz_png/PMZOEonJxWdEy0ZPFSJ5Z68A23ZKOicMuxTxueyul32mFDaW01wBlfpniayURRWu1mlq1YTf0vEUBdKrtr2SUQWw/640?wx_fmt=png&quot;);background-position: center top;background-repeat: no-repeat;background-size: 75px;line-height: 95px;margin-top: 38px;margin-bottom: 10px;"><span style="font-size: 20px;color: #48b378;border-bottom: 2px solid #2e7950;">3.定时任务</span></h1> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">假如我们要快速搞搞,数据量有没那么大,怎么办呢?定时任务也可以。</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.9144542772861357" src="/upload/d0cb783b5442149facd06bbfa93cd2db.png" data-type="png" data-w="678" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> <figcaption style="margin-top: 5px;text-align: center;color: rgb(136, 136, 136);font-size: 12px;font-family: PingFangSC-Light;"> 定时任务 </figcaption> </figure> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">定时任务,最麻烦的一点是频率不好选,频率高的话,会非自然地形成业务的波峰,导致存储的CPU、内存占用波峰式上升,频率低的话实时性比较差,而且也有波峰的情况。</p> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">这种方式:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 优点:实现比较简单 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 缺点: </section></li> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;list-style-type: square;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 实时性难以保证 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 对存储压力较大 </section></li> </ul> </ul> <h1 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 24px;text-align: center;background-image: url(&quot;https://mmbiz.qpic.cn/mmbiz_png/PMZOEonJxWdEy0ZPFSJ5Z68A23ZKOicMuxTxueyul32mFDaW01wBlfpniayURRWu1mlq1YTf0vEUBdKrtr2SUQWw/640?wx_fmt=png&quot;);background-position: center top;background-repeat: no-repeat;background-size: 75px;line-height: 95px;margin-top: 38px;margin-bottom: 10px;"><span style="font-size: 20px;color: #48b378;border-bottom: 2px solid #2e7950;">4.数据订阅</span></h1> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">还有一种方式,就是最时兴的数据订阅。</p> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">MySQL通过binlog订阅实现主从同步,各路数据订阅框架比如canal就依据这个原理,将client组件伪装成从库,来实现数据订阅。</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.3819672131147541" src="/upload/bfb99e8f5f38e696d197d89772942c56.png" data-type="png" data-w="1220" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> <figcaption style="margin-top: 5px;text-align: center;color: rgb(136, 136, 136);font-size: 12px;font-family: PingFangSC-Light;"> MySQL主从同步 </figcaption> </figure> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">我们以应用最广泛的canal为例,canal通过<code style="font-size: 14px;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(40, 202, 113);">canal-adapter</code>,支持多种适配器,其中就有ES适配器,通过一些配置,启动之后,就可以直接把MySQL数据同步到ES,这个过程是零代码的。</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.7479508196721312" src="/upload/8f329af290e5563c7f1cd9649cec4849.png" data-type="png" data-w="976" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> <figcaption style="margin-top: 5px;text-align: center;color: rgb(136, 136, 136);font-size: 12px;font-family: PingFangSC-Light;"> canal同步数据 </figcaption> </figure> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">但是,和老板了解过,使用canal看起来很美好,帮我们把同步的事情都干了,但其实,还是要写代码。为什么呢?</p> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">前面提到的多张表数据聚合,canal的支持没那么好,所以还是得回查。这时候用canal-adapter就不合适了,需要自己实现canal-client,监听和聚合数据,写入ES:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.8018648018648019" src="/upload/56b61437f99b812f50d2350792db0363.png" data-type="png" data-w="858" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> <figcaption style="margin-top: 5px;text-align: center;color: rgb(136, 136, 136);font-size: 12px;font-family: PingFangSC-Light;"> 数据订阅+回查 </figcaption> </figure> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">这种看起来和异步双写比较像,但是第一降低了商品服务的耦合,第二数据的实时性更好。</p> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">所以使用数据订阅:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 优点: </section></li> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;list-style-type: square;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 业务入侵较少 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 实时性较好 </section></li> </ul> </ul> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">至于数据订阅框架的选型,主流的大体上是这些:</p> <section data-tool="mdnice编辑器" style="overflow-x: auto;"> <table> <thead> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <th style="border-top-width: 1px;border-color: rgb(204, 204, 204);text-align: left;background-color: rgb(240, 240, 240);font-size: 14px;min-width: 85px;"><br></th> <th style="border-top-width: 1px;border-color: rgb(204, 204, 204);text-align: left;background-color: rgb(240, 240, 240);font-size: 14px;min-width: 85px;">Cancal</th> <th style="border-top-width: 1px;border-color: rgb(204, 204, 204);text-align: left;background-color: rgb(240, 240, 240);font-size: 14px;min-width: 85px;">Maxwell</th> <th style="border-top-width: 1px;border-color: rgb(204, 204, 204);text-align: left;background-color: rgb(240, 240, 240);font-size: 14px;min-width: 85px;">Python-Mysql-Rplication</th> </tr> </thead> <tbody style="border-width: 0px;border-style: initial;border-color: initial;"> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">开源方</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">阿里巴巴</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">Zendesk</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">社区</td> </tr> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: rgb(248, 248, 248);"> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">开发语言</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">Java</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">Java</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">Python</td> </tr> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">活跃度</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">活跃</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">活跃</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">活跃</td> </tr> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: rgb(248, 248, 248);"> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">高可用</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">支持</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">支持</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">不支持</td> </tr> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">客户端</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">Java/Go/PHP/Python/Rust</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">无</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">Python</td> </tr> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: rgb(248, 248, 248);"> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">消息落地</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">Kafka/RocketMQ 等</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">Kafka/RabbitNQ/Redis 等</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">自定义</td> </tr> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">消息格式</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">自定义</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">JSON</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">自定义</td> </tr> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: rgb(248, 248, 248);"> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">文档详略</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">详细</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">详细</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">详细</td> </tr> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">Boostrap</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">不支持</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">支持</td> <td style="border-color: rgb(204, 204, 204);font-size: 14px;min-width: 85px;">不支持</td> </tr> </tbody> </table> </section> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">除了MySQL同步ES,MySQL同步到其它的数据存储,例如HBase,其实大体上都是类似的几种方法。</p> <br data-tool="mdnice编辑器"> <hr data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;height: 1px;border-width: initial;border-style: none;border-color: initial;text-align: center;background-image: linear-gradient(to right, rgba(93, 186, 133, 0), rgba(93, 186, 133, 0.75), rgba(93, 186, 133, 0));"> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;"><strong style="line-height: 1.75em;">参考:</strong></p> <ul class="list-paddingleft-1" style="list-style-type: circle;"> <li> <section style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: normal;"> <span style="font-size: 10px;">[1]. https://www.infoq.cn/article/1afyz3b6hnhprrg12833</span> </section></li> <li> <section style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: normal;"> <span style="font-size: 10px;">[2].https://www.iamle.com/archives/2900.html</span> </section></li> <li> <section style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: normal;"> <span style="font-size: 10px;">[3].https://blog.51cto.com/lianghecai/4755693</span> </section></li> <li> <section style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: normal;"> <span style="font-size: 10px;">[4].https://qinyuanpei.github.io/posts/1333693167/</span> </section></li> <li> <section style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: normal;"> <span style="font-size: 10px;">[5].https://github.com/alibaba/canal/wiki/ClientAdapter</span> </section></li> </ul> <hr data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;height: 1px;border-width: initial;border-style: none;border-color: initial;text-align: center;background-image: linear-gradient(to right, rgba(93, 186, 133, 0), rgba(93, 186, 133, 0.75), rgba(93, 186, 133, 0));"> </section> <section> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-weui-theme="light" data-id="MzkwODE5ODM0Ng==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/PMZOEonJxWdFLJg0sAOqwHB1mb24icMADUgxm1qZQft5aN3H37NAmQnOvpGB7J9JVHxC6NSiacxbBP1DYdhIAeyA/0?wx_fmt=png" data-nickname="三分恶" data-alias="Fighter3FullStack" data-signature="CSDN博客专家、优质创作者,华为云云享专家;肝过外包、混过国企,目前在一家跨境电商搬砖;写过诗,打过拳,佛系小码农。认真讲技术,随性侃人生,关注我,我们一起走的更远。" data-from="0" data-is_biz_ban="0"></mp-common-profile> </section> <section> <span style="font-family: Optima-Regular, PingFangTC-light;">技术交流群持续开放中,欢迎添加我的个人微信:ThirdFighter,新年,让我们一起进步。</span> </section> <p style="text-align: center;"><img class="rich_pages wxw-img" data-backh="512" data-backw="512" data-galleryid="" data-ratio="1" data-s="300,640" src="/upload/e8acd6d0b6913be395851d2d5dbf334c.jpg" data-type="jpeg" data-w="512" style="width: 100%;height: auto;"></p> <section> <span style="font-family: Optima-Regular, PingFangTC-light;"></span> </section> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>

百度工程师带你玩转正则

作者:微信小助手

<p style="text-align: center;margin-bottom: 0em;margin-left: 8px;margin-right: 8px;" data-mpa-powered-by="yiban.io"><img class="rich_pages wxw-img" data-backh="88" data-backw="562" data-cropselx1="0" data-cropselx2="562" data-cropsely1="0" data-cropsely2="374" data-galleryid="" data-ratio="0.15627906976744185" data-s="300,640" src="/upload/e98c6161e3fde9b9ab0f9920ebd35ebf.png" data-type="jpeg" data-w="1075" 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;width: 100%;"><br></p> <section style="text-align: left;margin-bottom: 0em;margin-left: 8px;margin-right: 8px;"> <br> </section> <section style="text-align: center;margin-bottom: 0em;margin-left: 8px;margin-right: 8px;"> <span style="font-size: 12px;font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 1px;orphans: 2;text-align: justify;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;caret-color: rgb(0, 0, 0);background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;float: none;color: rgb(136, 136, 136);display: inline !important;">作者 |&nbsp;向阳</span> </section> <section style="text-align: center;margin-bottom: 0em;margin-left: 8px;margin-right: 8px;"> <span style="font-size: 12px;font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 1px;orphans: 2;text-align: justify;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;caret-color: rgb(0, 0, 0);background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;float: none;color: rgb(136, 136, 136);display: inline !important;"></span> </section> <section style="text-align: center;margin-bottom: 0em;margin-left: 8px;margin-right: 8px;"> <br> </section> <section powered-by="xiumi.us" style="margin: 10px 0px 0px;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box;outline: 0px;display: block;color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.544px;orphans: 2;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;visibility: visible;"> <section style="margin: 0px;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box;outline: 0px;display: block;font-size: 16px;text-align: center;line-height: 0;visibility: visible;"> <section style="margin: 0px 8px;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box;outline: 0px;display: block;clear: both;min-height: 1em;visibility: visible;"> 导读&nbsp; </section> <section style="margin: 0px 8px;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box;outline: 0px;display: block;clear: both;min-height: 1em;visibility: visible;"> <span style="margin: 0px;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box;outline: 0px;font-size: 12px;color: rgb(160, 160, 160);visibility: visible;">introduction</span> </section> </section> </section> <section style="margin: 0px 8px;padding: 0px;max-width: 100%;box-sizing: border-box;outline: 0px;display: block;color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.544px;orphans: 2;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;background-color: rgb(255, 255, 255);font-size: 15px;line-height: 1.75;visibility: visible;overflow-wrap: break-word !important;"> <section powered-by="xiumi.us" style="margin: 4px 0px 10px;padding: 0px;max-width: 100%;box-sizing: border-box;outline: 0px;display: flex;text-align: center;justify-content: center;flex-flow: row nowrap;visibility: visible;overflow-wrap: break-word !important;"> <section style="margin: 0px 5px 0px 0px;padding: 0px;max-width: 100%;box-sizing: border-box;outline: 0px;display: inline-block;vertical-align: top;width: 10px;flex: 0 0 auto;height: auto;align-self: flex-start;visibility: visible;overflow-wrap: break-word !important;"> <section powered-by="xiumi.us" style="margin: 0px 0px 10px;padding: 0px;max-width: 100%;box-sizing: border-box;outline: 0px;display: block;visibility: visible;overflow-wrap: break-word !important;"> <section style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box;outline: 0px;display: block;width: 10px;height: 5px;background-color: rgb(95, 156, 239);visibility: visible;overflow-wrap: break-word !important;"> <svg viewbox="0 0 1 1" style="float: left;line-height: 0;width: 0px;vertical-align: top;visibility: visible;"></svg> </section> </section> </section> <section style="margin: 0px 5px 0px 0px;padding: 0px;max-width: 100%;box-sizing: border-box;outline: 0px;display: inline-block;vertical-align: top;width: 10px;flex: 0 0 auto;height: auto;align-self: flex-start;visibility: visible;overflow-wrap: break-word !important;"> <section powered-by="xiumi.us" style="margin: 0px 0px 10px;padding: 0px;max-width: 100%;box-sizing: border-box;outline: 0px;display: block;visibility: visible;overflow-wrap: break-word !important;"> <section style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box;outline: 0px;display: block;width: 10px;height: 5px;background-color: rgb(249, 110, 87);visibility: visible;overflow-wrap: break-word !important;"> <svg viewbox="0 0 1 1" style="float: left;line-height: 0;width: 0px;vertical-align: top;visibility: visible;"></svg> </section> </section> </section> </section> </section> <section style="margin: 0px 8px;padding: 0.5em 1em;max-width: 100%;outline: 0px;display: block;color: rgb(34, 34, 34);font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-family: -apple-system, 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;border-style: none;background-color: rgb(245, 245, 245);letter-spacing: 0.612px;visibility: visible;line-height: 1.75em;overflow-wrap: break-word !important;box-sizing: border-box !important;"> <span style="color: rgb(136, 136, 136);font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 1px;">在很多技术领域,都有正则的身影。但许多像我一样的人,只闻其名。因此将正则常用知识汇总,便于查阅。正则表达式(Regular Expression)是用于描述一组字符串特征的模式,用来匹配特定的字符串。通过特殊字符+普通字符来进行模式描述,从而达到文本匹配目的工具。因此正则表达式是用于匹配字符串中字符组合的模式。</span> </section> <section style="margin: 0px 8px;padding: 0.5em 1em;max-width: 100%;outline: 0px;display: block;color: rgb(34, 34, 34);font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-family: -apple-system, 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;border-style: none;background-color: rgb(245, 245, 245);letter-spacing: 0.612px;visibility: visible;line-height: 1.75em;overflow-wrap: break-word !important;box-sizing: border-box !important;"> <span style="color: rgb(136, 136, 136);font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 1px;">正则表达式可以很方便的提取我们想要的信息,所以正则表达式是一个很重要的知识点!</span> <span style="color: rgb(136, 136, 136);font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;letter-spacing: 1px;">欢迎大家一起学习~</span> </section> <section style="margin: 0px 8px 0em;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;outline: 0px;display: block;color: rgb(34, 34, 34);font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 0.544px;orphans: 2;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-family: -apple-system, 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);visibility: visible;line-height: 1.75em;"> <br style="margin: 0px;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;outline: 0px;visibility: visible;"> </section> <section style="margin: 0px 8px 0em;padding: 0.5em 1em;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;outline: 0px;display: block;color: rgb(34, 34, 34);font-size: 17px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;orphans: 2;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-family: -apple-system, 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;border-style: none;background-color: rgb(245, 245, 245);letter-spacing: 0.612px;visibility: visible;line-height: 1.75em;"> <span style="margin: 0px;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;outline: 0px;font-size: 15px;visibility: visible;letter-spacing: 1px;"><em style="margin: 0px;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;outline: 0px;font-style: italic;visibility: visible;"><span style="margin: 0px;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;outline: 0px;color: rgb(136, 136, 136);visibility: visible;">全文4082字,预计阅读时间11分钟。</span></em></span> </section> <section style="font-weight: 400;margin: 10px 0% -40px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="font-size: 53px;color: rgb(238, 238, 238);text-align: center;line-height: 1;letter-spacing: 0px;box-sizing: border-box;"> <section style="margin: 0px 8px;padding: 0px;box-sizing: border-box;"> <br> </section> </section> </section> <section powered-by="xiumi.us" style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box;color: rgb(51, 51, 51);font-family: mp-quote, -apple-system-font, &quot;system-ui&quot;, &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-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;text-align: center;justify-content: center;display: flex;flex-flow: row nowrap;overflow-wrap: break-word !important;"> <section style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box;display: inline-block;width: auto;vertical-align: top;min-width: 10%;flex: 0 0 auto;height: auto;align-self: flex-start;line-height: 0;overflow-wrap: break-word !important;"> <section powered-by="xiumi.us" style="margin: 0px;padding: 0px 15px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box;font-size: 24px;letter-spacing: 4px;color: rgb(95, 156, 239);"> <p style="margin: 0px;padding: 0px;clear: both;min-height: 1em;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box;"><span style="margin: 0px;padding: 0px;max-width: 100%;font-size: 20px;overflow-wrap: break-word !important;box-sizing: border-box !important;"><strong style="margin: 0px;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box;">01</strong></span></p> </section> <section powered-by="xiumi.us" style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"> <section style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box;background-color: rgb(92, 92, 92);height: 1px;overflow-wrap: break-word !important;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <section powered-by="xiumi.us" style="margin: 0px 0px 10px;padding: 0px;max-width: 100%;box-sizing: border-box;color: rgb(51, 51, 51);font-family: mp-quote, -apple-system-font, &quot;system-ui&quot;, &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-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;overflow-wrap: break-word !important;"> <section style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box;text-align: center;color: rgb(95, 156, 239);line-height: 2;overflow-wrap: break-word !important;"> <p style="margin: 0px;padding: 0px;clear: both;min-height: 1em;max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><span style="font-size: 20px;"><strong>正则概述</strong></span><strong style="font-size: 20px;"></strong></p> </section> </section> <p style="caret-color: rgb(0, 0, 0);color: rgb(0, 0, 0);white-space: normal;text-size-adjust: auto;text-align: justify;line-height: 1.75em;margin-bottom: 0px;margin-left: 8px;margin-right: 8px;"><span style="background-color: rgb(255, 255, 255);color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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: 15px;letter-spacing: 1px;">正则表达式是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象。</span></p> <p style="caret-color: rgb(0, 0, 0);color: rgb(0, 0, 0);white-space: normal;text-size-adjust: auto;text-align: justify;line-height: 1.75em;margin-bottom: 0px;margin-left: 8px;margin-right: 8px;"><span style="background-color: rgb(255, 255, 255);color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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: 15px;letter-spacing: 1px;"><br></span></p> <section powered-by="xiumi.us" style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box;color: rgb(51, 51, 51);font-family: mp-quote, -apple-system-font, &quot;system-ui&quot;, &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-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;text-align: center;justify-content: center;display: flex;flex-flow: row nowrap;overflow-wrap: break-word !important;"> <section style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box;display: inline-block;width: auto;vertical-align: top;min-width: 10%;flex: 0 0 auto;height: auto;align-self: flex-start;line-height: 0;overflow-wrap: break-word !important;"> <section powered-by="xiumi.us" style="margin: 0px;padding: 0px 15px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box;font-size: 24px;letter-spacing: 4px;color: rgb(95, 156, 239);"> <p style="margin: 0px;padding: 0px;clear: both;min-height: 1em;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box;"><span style="margin: 0px;padding: 0px;max-width: 100%;font-size: 20px;overflow-wrap: break-word !important;box-sizing: border-box !important;"><strong style="margin: 0px;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box;">02</strong></span></p> </section> <section powered-by="xiumi.us" style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"> <section style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box;background-color: rgb(92, 92, 92);height: 1px;overflow-wrap: break-word !important;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <section powered-by="xiumi.us" style="margin: 0px 0px 10px;padding: 0px;max-width: 100%;box-sizing: border-box;color: rgb(51, 51, 51);font-family: mp-quote, -apple-system-font, &quot;system-ui&quot;, &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-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;overflow-wrap: break-word !important;"> <section style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box;text-align: center;color: rgb(95, 156, 239);line-height: 2;overflow-wrap: break-word !important;"> <p style="margin: 0px;padding: 0px;clear: both;min-height: 1em;max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"><span style="font-size: 20px;"><strong>基本语法</strong></span></p> </section> </section> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="caret-color: rgb(0, 0, 0);color: rgb(0, 0, 0);white-space: normal;text-size-adjust: auto;text-align: justify;line-height: 1.75em;margin-bottom: 0px;margin-left: 8px;margin-right: 8px;"> <section style="font-size: 15px;line-height: 1.75;box-sizing: border-box;font-style: normal;font-weight: 400;text-align: justify;margin-bottom: 0px;margin-left: 8px;margin-right: 8px;"> <section style="display: flex;flex-flow: row nowrap;margin: 10px 0px;text-align: left;justify-content: flex-start;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: bottom;width: auto;flex: 0 0 0%;height: auto;align-self: flex-end;margin: 0px 4px 0px 0px;box-sizing: border-box;"> <section style="transform: perspective(0px);transform-style: flat;box-sizing: border-box;" powered-by="xiumi.us"> <section style="text-align: center;transform: rotateX(180deg);box-sizing: border-box;"> <section style="display: inline-block;width: 3px;height: 10px;vertical-align: top;overflow: hidden;background-color: rgb(169, 207, 245);box-sizing: border-box;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;flex: 0 0 0%;height: auto;align-self: flex-end;box-sizing: border-box;"> <section style="transform: perspective(0px);transform-style: flat;box-sizing: border-box;" powered-by="xiumi.us"> <section style="text-align: center;transform: rotateX(180deg);margin: 0px;box-sizing: border-box;"> <section style="display: inline-block;width: 3px;height: 16px;vertical-align: top;overflow: hidden;background-color: rgb(169, 207, 245);box-sizing: border-box;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;border-bottom: 1px solid rgb(169, 207, 245);border-bottom-right-radius: 0px;flex: 0 0 auto;align-self: flex-end;min-width: 10%;max-width: 100%;height: auto;padding: 4px 4px 4px 11px;margin: 0px;box-sizing: border-box;"> <section style="text-align: justify;color: rgb(95, 156, 239);box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><strong style="box-sizing: border-box;">2.1 定义方式</strong></p> </section> </section> </section> </section> <p style="caret-color: rgb(0, 0, 0);color: rgb(0, 0, 0);white-space: normal;text-size-adjust: auto;text-align: justify;line-height: 1.75em;margin-bottom: 0px;margin-left: 8px;margin-right: 8px;"><span style="caret-color: rgb(0, 0, 0);background-color: rgb(255, 255, 255);color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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: 15px;letter-spacing: 1px;">字面量方式:/^\d+$/g,</span></p> <p style="caret-color: rgb(0, 0, 0);color: rgb(0, 0, 0);white-space: normal;text-size-adjust: auto;text-align: justify;line-height: 1.75em;margin-bottom: 0px;margin-left: 8px;margin-right: 8px;"><span style="caret-color: rgb(0, 0, 0);background-color: rgb(255, 255, 255);color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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: 15px;letter-spacing: 1px;">new RegExp("^\\d+$", "g")</span></p> <section style="font-size: 15px;line-height: 1.75;box-sizing: border-box;font-style: normal;font-weight: 400;text-align: justify;margin-bottom: 0px;margin-left: 8px;margin-right: 8px;"> <section style="display: flex;flex-flow: row nowrap;margin: 10px 0px;text-align: left;justify-content: flex-start;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: bottom;width: auto;flex: 0 0 0%;height: auto;align-self: flex-end;margin: 0px 4px 0px 0px;box-sizing: border-box;"> <section style="transform: perspective(0px);transform-style: flat;box-sizing: border-box;" powered-by="xiumi.us"> <section style="text-align: center;transform: rotateX(180deg);box-sizing: border-box;"> <section style="display: inline-block;width: 3px;height: 10px;vertical-align: top;overflow: hidden;background-color: rgb(169, 207, 245);box-sizing: border-box;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;flex: 0 0 0%;height: auto;align-self: flex-end;box-sizing: border-box;"> <section style="transform: perspective(0px);transform-style: flat;box-sizing: border-box;" powered-by="xiumi.us"> <section style="text-align: center;transform: rotateX(180deg);margin: 0px;box-sizing: border-box;"> <section style="display: inline-block;width: 3px;height: 16px;vertical-align: top;overflow: hidden;background-color: rgb(169, 207, 245);box-sizing: border-box;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;border-bottom: 1px solid rgb(169, 207, 245);border-bottom-right-radius: 0px;flex: 0 0 auto;align-self: flex-end;min-width: 10%;max-width: 100%;height: auto;padding: 4px 4px 4px 11px;margin: 0px;box-sizing: border-box;"> <section style="text-align: justify;color: rgb(95, 156, 239);box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><strong style="box-sizing: border-box;">2.2 修饰符</strong></p> </section> </section> </section> </section> <section style="text-align: center;margin-left: 8px;margin-right: 8px;"> <img class="rich_pages wxw-img js_insertlocalimg" data-backh="300" data-backw="562" data-ratio="0.5336879432624113" data-s="300,640" src="/upload/54c8956a98a69396b1230b557e710e19.png" data-type="png" data-w="1128" style="width: 100%;height: auto;"> </section> <section style="font-size: 15px;line-height: 1.75;box-sizing: border-box;font-style: normal;font-weight: 400;text-align: justify;margin-bottom: 0px;margin-left: 8px;margin-right: 8px;"> <section style="display: flex;flex-flow: row nowrap;margin: 10px 0px;text-align: left;justify-content: flex-start;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: bottom;width: auto;flex: 0 0 0%;height: auto;align-self: flex-end;margin: 0px 4px 0px 0px;box-sizing: border-box;"> <section style="transform: perspective(0px);transform-style: flat;box-sizing: border-box;" powered-by="xiumi.us"> <section style="text-align: center;transform: rotateX(180deg);box-sizing: border-box;"> <section style="display: inline-block;width: 3px;height: 10px;vertical-align: top;overflow: hidden;background-color: rgb(169, 207, 245);box-sizing: border-box;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;flex: 0 0 0%;height: auto;align-self: flex-end;box-sizing: border-box;"> <section style="transform: perspective(0px);transform-style: flat;box-sizing: border-box;" powered-by="xiumi.us"> <section style="text-align: center;transform: rotateX(180deg);margin: 0px;box-sizing: border-box;"> <section style="display: inline-block;width: 3px;height: 16px;vertical-align: top;overflow: hidden;background-color: rgb(169, 207, 245);box-sizing: border-box;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;border-bottom: 1px solid rgb(169, 207, 245);border-bottom-right-radius: 0px;flex: 0 0 auto;align-self: flex-end;min-width: 10%;max-width: 100%;height: auto;padding: 4px 4px 4px 11px;margin: 0px;box-sizing: border-box;"> <section style="text-align: justify;color: rgb(95, 156, 239);box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><strong style="box-sizing: border-box;">2.3 元字符</strong></p> </section> </section> </section> </section> <p style="text-align: left;margin-left: 8px;margin-right: 8px;caret-color: rgb(0, 0, 0);white-space: normal;text-size-adjust: auto;line-height: 1.75em;margin-bottom: 0px;"><span style="text-align: justify;background-color: rgb(255, 255, 255);color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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: 15px;letter-spacing: 1px;">一个正则表达式模式是由简单的字符所构成的,比如 /abc/;或者是简单和特殊字符的组合,比如 /ab*c/</span></p> <section style="text-align: center;margin-left: 8px;margin-right: 8px;"> <img class="rich_pages wxw-img js_insertlocalimg" data-backh="653" data-backw="562" data-ratio="1.162471395881007" data-s="300,640" src="/upload/34ace28e293977677fe6a50fddc26de6.png" data-type="png" data-w="874" style="width: 100%;height: auto;"> </section> <section style="font-size: 15px;line-height: 1.75;box-sizing: border-box;font-style: normal;font-weight: 400;text-align: justify;margin-bottom: 0px;margin-left: 8px;margin-right: 8px;"> <section style="display: flex;flex-flow: row nowrap;margin: 10px 0px;text-align: left;justify-content: flex-start;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: bottom;width: auto;flex: 0 0 0%;height: auto;align-self: flex-end;margin: 0px 4px 0px 0px;box-sizing: border-box;"> <section style="transform: perspective(0px);transform-style: flat;box-sizing: border-box;" powered-by="xiumi.us"> <section style="text-align: center;transform: rotateX(180deg);box-sizing: border-box;"> <section style="display: inline-block;width: 3px;height: 10px;vertical-align: top;overflow: hidden;background-color: rgb(169, 207, 245);box-sizing: border-box;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;flex: 0 0 0%;height: auto;align-self: flex-end;box-sizing: border-box;"> <section style="transform: perspective(0px);transform-style: flat;box-sizing: border-box;" powered-by="xiumi.us"> <section style="text-align: center;transform: rotateX(180deg);margin: 0px;box-sizing: border-box;"> <section style="display: inline-block;width: 3px;height: 16px;vertical-align: top;overflow: hidden;background-color: rgb(169, 207, 245);box-sizing: border-box;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;border-bottom: 1px solid rgb(169, 207, 245);border-bottom-right-radius: 0px;flex: 0 0 auto;align-self: flex-end;min-width: 10%;max-width: 100%;height: auto;padding: 4px 4px 4px 11px;margin: 0px;box-sizing: border-box;"> <section style="text-align: justify;color: rgb(95, 156, 239);box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><strong style="box-sizing: border-box;">2.4&nbsp;其他断言</strong></p> </section> </section> </section> </section> <p style="text-align: left;margin-left: 8px;margin-right: 8px;caret-color: rgb(0, 0, 0);white-space: normal;text-size-adjust: auto;line-height: 1.75em;margin-bottom: 0px;"><span style="text-align: justify;background-color: rgb(255, 255, 255);color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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: 15px;letter-spacing: 1px;">断言的组成之一是边界。对于文本、词或模式,边界可以用来表明它们的起始或终止部分,分为边界类断言与其他断言。边界类断言有 ^, $, \b, \B,其他断言有 x(?=y), x(?!y), (?&lt;=y)x, (?&lt;!y)x。</span></p> <section style="text-align: center;margin-left: 8px;margin-right: 8px;"> <img class="rich_pages wxw-img js_insertlocalimg" data-backh="151" data-backw="562" data-ratio="0.26875" data-s="300,640" src="/upload/ccab9cb42077911bee5196e7e3e6cc9b.png" data-type="png" data-w="1280" style="width: 100%;height: auto;"> </section> <p style="text-align: left;margin-left: 8px;margin-right: 8px;caret-color: rgb(0, 0, 0);white-space: normal;text-size-adjust: auto;line-height: 1.75em;margin-bottom: 0px;color: rgb(0, 0, 0);"><span style="color: rgb(120, 172, 254);"><strong><em><span style="color: rgb(120, 172, 254);text-align: justify;background-color: rgb(255, 255, 255);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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: 15px;letter-spacing: 1px;">注:需要关注写法与真正匹配到的字符串!!!</span></em></strong></span></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;caret-color: rgb(0, 0, 0);white-space: normal;text-size-adjust: auto;line-height: 1.75em;margin-bottom: 0px;"><br></p> </section> <section powered-by="xiumi.us" style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box;color: rgb(51, 51, 51);font-family: mp-quote, -apple-system-font, &quot;system-ui&quot;, &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-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 15px;text-align: center;justify-content: center;display: flex;flex-flow: row nowrap;overflow-wrap: break-word !important;"> <section style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box;display: inline-block;width: auto;vertical-align: top;min-width: 10%;flex: 0 0 auto;height: auto;align-self: flex-start;line-height: 0;overflow-wrap: break-word !important;"> <section powered-by="xiumi.us" style="margin: 0px;padding: 0px 15px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box;font-size: 24px;letter-spacing: 4px;color: rgb(95, 156, 239);"> <p style="margin: 0px;padding: 0px;clear: both;min-height: 1em;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box;"><span style="margin: 0px;padding: 0px;max-width: 100%;font-size: 20px;overflow-wrap: break-word !important;box-sizing: border-box !important;"><strong style="margin: 0px;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box;">03</strong></span></p> </section> <section powered-by="xiumi.us" style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"> <section style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box;background-color: rgb(92, 92, 92);height: 1px;overflow-wrap: break-word !important;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <section powered-by="xiumi.us" style="margin: 0px;padding: 0px;clear: both;min-height: 1em;max-width: 100%;box-sizing: border-box;text-align: center;color: rgb(95, 156, 239);line-height: 2;font-family: mp-quote, -apple-system-font, &quot;system-ui&quot;, &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-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;overflow-wrap: break-word !important;"> <section style="margin: 0px;padding: 0px;clear: both;min-height: 1em;max-width: 100%;box-sizing: border-box;text-align: center;color: rgb(95, 156, 239);line-height: 2;font-family: mp-quote, -apple-system-font, &quot;system-ui&quot;, &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-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;overflow-wrap: break-word !important;"> <h2 style="margin: 0px;padding: 0px;clear: both;min-height: 1em;max-width: 100%;box-sizing: border-box;text-align: center;color: rgb(95, 156, 239);line-height: 2;font-family: mp-quote, -apple-system-font, &quot;system-ui&quot;, &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-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;overflow-wrap: break-word !important;"><span style="font-size: 20px;"><strong>正则对象的属性和方法</strong></span></h2> </section> </section> <section style="font-size: 15px;line-height: 1.75;box-sizing: border-box;font-style: normal;font-weight: 400;text-align: justify;margin-bottom: 0px;margin-left: 8px;margin-right: 8px;"> <section style="display: flex;flex-flow: row nowrap;margin: 10px 0px;text-align: left;justify-content: flex-start;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: bottom;width: auto;flex: 0 0 0%;height: auto;align-self: flex-end;margin: 0px 4px 0px 0px;box-sizing: border-box;"> <section style="transform: perspective(0px);transform-style: flat;box-sizing: border-box;" powered-by="xiumi.us"> <section style="text-align: center;transform: rotateX(180deg);box-sizing: border-box;"> <section style="display: inline-block;width: 3px;height: 10px;vertical-align: top;overflow: hidden;background-color: rgb(169, 207, 245);box-sizing: border-box;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;flex: 0 0 0%;height: auto;align-self: flex-end;box-sizing: border-box;"> <section style="transform: perspective(0px);transform-style: flat;box-sizing: border-box;" powered-by="xiumi.us"> <section style="text-align: center;transform: rotateX(180deg);margin: 0px;box-sizing: border-box;"> <section style="display: inline-block;width: 3px;height: 16px;vertical-align: top;overflow: hidden;background-color: rgb(169, 207, 245);box-sizing: border-box;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;border-bottom: 1px solid rgb(169, 207, 245);border-bottom-right-radius: 0px;flex: 0 0 auto;align-self: flex-end;min-width: 10%;max-width: 100%;height: auto;padding: 4px 4px 4px 11px;margin: 0px;box-sizing: border-box;"> <section style="text-align: justify;color: rgb(95, 156, 239);box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><strong style="box-sizing: border-box;">3.1 属性</strong></p> </section> </section> </section> </section> <p style="text-align: center;margin-left: 8px;margin-right: 8px;margin-bottom: 0px;"><img class="rich_pages wxw-img js_insertlocalimg" data-backh="553" data-backw="578" data-ratio="0.9573033707865168" data-s="300,640" src="/upload/8f176d4f2efde2ffe8f7b6bd3b7a251a.png" data-type="png" data-w="890" style="width: 100%;height: auto;"></p> <h2 style="margin: 0px 8px;padding: 0px;font-weight: 400;font-size: 16px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;orphans: 2;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;outline: 0px;font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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;color: rgb(34, 34, 34);letter-spacing: 0.544px;background-color: rgb(255, 255, 255);line-height: 1.75em;"><em style="margin: 0px;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;outline: 0px;font-style: italic;color: rgb(0, 0, 0);font-family: -apple-system, &quot;system-ui&quot;, &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: 14px;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: 1px;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;caret-color: rgb(0, 0, 0);background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;"><span style="margin: 0px;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;outline: 0px;font-size: 14px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;"><em style="margin: 0px;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;outline: 0px;font-style: italic;font-family: -apple-system, &quot;system-ui&quot;, &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;"><span style="margin: 0px;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;outline: 0px;font-size: 14px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;color: rgb(136, 136, 136);"><em style="margin: 0px;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;outline: 0px;font-style: italic;color: rgb(0, 0, 0);font-size: 14px;white-space: normal;caret-color: rgb(0, 0, 0);"><span style="margin: 0px;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;outline: 0px;font-size: 14px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;"><em style="margin: 0px;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;outline: 0px;font-style: italic;font-family: -apple-system, &quot;system-ui&quot;, &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;"><span style="margin: 0px;padding: 0px;max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;outline: 0px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 14px;color: rgb(136, 136, 136);">△正则属性和方法</span></em></span></em></span></em></span></em></h2> <p style="margin-bottom: 0px;"><br></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;margin-bottom: 0px;"><img class="rich_pages wxw-img js_insertlocalimg" data-backh="353" data-backw="578" data-ratio="0.6109375" data-s="300,640" src="/upload/5ea437265bedc177790123addc2c7fad.png" data-type="png" data-w="1280" style="width: 100%;height: auto;"></p> <p style="text-align: left;margin-left: 8px;margin-right: 8px;caret-color: rgb(0, 0, 0);white-space: normal;text-size-adjust: auto;line-height: 1.75em;margin-bottom: 0px;"><br></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="javascript"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">var</span> reg=<span class="code-snippet__regexp">/ab/g</span>;</span></code><code><span class="code-snippet_outer">reg.ignoreCase; <span class="code-snippet__comment">// false,检测是否含有i 属性</span></span></code><code><span class="code-snippet_outer">reg.global; <span class="code-snippet__comment">// true,检测是否含有g 属性</span></span></code><code><span class="code-snippet_outer">reg.multiline; <span class="code-snippet__comment">// false,检测是否含有m 属性</span></span></code><code><span class="code-snippet_outer">reg.source; <span class="code-snippet__comment">// "ab",匹配内容体</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">var</span> regex =<span class="code-snippet__keyword">new</span> <span class="code-snippet__built_in">RegExp</span>(<span class="code-snippet__string">"\u{61}"</span>,<span class="code-snippet__string">"u"</span>);</span></code><code><span class="code-snippet_outer">regex.unicode <span class="code-snippet__comment">// true</span></span></code></pre> </section> <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="javascript"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">const</span> str1 = <span class="code-snippet__string">"foo bar foo"</span>;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">const</span> regex1 = <span class="code-snippet__regexp">/foo/</span>dg;</span></code><code><span class="code-snippet_outer">regex1.hasIndices <span class="code-snippet__comment">// Output: true</span></span></code><code><span class="code-snippet_outer">regex1.exec(str1).indices[<span class="code-snippet__number">0</span>] <span class="code-snippet__comment">// Output: Array [0, 3]</span></span></code><code><span class="code-snippet_outer">regex1.exec(str1).indices[<span class="code-snippet__number">0</span>] <span class="code-snippet__comment">// Output: Array [8, 11]</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">const</span> str2 = <span class="code-snippet__string">"foo bar foo"</span>;</span></code><code><span class="code-snippet_outer"><span class="code-snippet__keyword">const</span> regex2 = <span class="code-snippet__regexp">/foo/</span>;</span></code><code><span class="code-snippet_outer">regex2.hasIndices <span class="code-snippet__comment">// Output: false</span></span></code><code><span class="code-snippet_outer">regex2.exec(str2).indices <span class="code-snippet__comment">// Output: undefined</span></span></code></pre> </section> <section style="font-size: 15px;line-height: 1.75;box-sizing: border-box;font-style: normal;font-weight: 400;text-align: justify;margin-bottom: 0px;margin-left: 8px;margin-right: 8px;"> <section style="display: flex;flex-flow: row nowrap;margin: 10px 0px;text-align: left;justify-content: flex-start;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: bottom;width: auto;flex: 0 0 0%;height: auto;align-self: flex-end;margin: 0px 4px 0px 0px;box-sizing: border-box;"> <section style="transform: perspective(0px);transform-style: flat;box-sizing: border-box;" powered-by="xiumi.us"> <section style="text-align: center;transform: rotateX(180deg);box-sizing: border-box;"> <section style="display: inline-block;width: 3px;height: 10px;vertical-align: top;overflow: hidden;background-color: rgb(169, 207, 245);box-sizing: border-box;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;flex: 0 0 0%;height: auto;align-self: flex-end;box-sizing: border-box;"> <section style="transform: perspective(0px);transform-style: flat;box-sizing: border-box;" powered-by="xiumi.us"> <section style="text-align: center;transform: rotateX(180deg);margin: 0px;box-sizing: border-box;"> <section style="display: inline-block;width: 3px;height: 16px;vertical-align: top;overflow: hidden;background-color: rgb(169, 207, 245);box-sizing: border-box;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;border-bottom: 1px solid rgb(169, 207, 245);border-bottom-right-radius: 0px;flex: 0 0 auto;align-self: flex-end;min-width: 10%;max-width: 100%;height: auto;padding: 4px 4px 4px 11px;margin: 0px;box-sizing: border-box;"> <section style="text-align: justify;color: rgb(95, 156, 239);box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><strong style="box-sizing: border-box;">3.2&nbsp;相关方法</strong></p> </section> </section> </section> </section> <p style="caret-color: rgb(0, 0, 0);color: rgb(0, 0, 0);white-space: normal;text-size-adjust: auto;text-align: left;line-height: 1.75em;margin-bottom: 0px;margin-left: 8px;margin-right: 8px;"><span style="background-color: rgb(255, 255, 255);color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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: 15px;letter-spacing: 1px;">这些模式被用于</span><span style="background-color: rgb(255, 255, 255);color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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: 15px;letter-spacing: 1px;">RegExp</span><span style="background-color: rgb(255, 255, 255);color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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: 15px;letter-spacing: 1px;">的</span><span style="background-color: rgb(255, 255, 255);color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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: 15px;letter-spacing: 1px;">exec</span><span style="background-color: rgb(255, 255, 255);color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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: 15px;letter-spacing: 1px;">和</span><span style="background-color: rgb(255, 255, 255);color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &quot;Helvetica Neue&quot;, &quot;PingF

MySQL 主从模式采用 GTID 的实践

作者:微信小助手

<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;line-height: 1.6;word-break: break-word;text-align: left;font-size: 15px;color: rgb(53, 53, 53);word-spacing: 0.8px;letter-spacing: 0.8px;border-radius: 16px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;visibility: visible;"> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="line-height: 1.6;word-break: break-word;text-align: left;font-size: 15px;color: rgb(53, 53, 53);word-spacing: 0.8px;letter-spacing: 0.8px;border-radius: 16px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;"> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">本文主要内容如下:</p> <p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.3470319634703196" data-s="300,640" src="/upload/7fe60385c7870d229dece13163f0270b.png" data-type="png" data-w="1752" style=""></p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 22px;margin-top: 20px;margin-right: 10px;"><span style="display: none;"></span><span style="font-size: 18px;color: rgb(34, 34, 34);display: inline-block;padding-left: 10px;border-left: 5px solid rgb(248, 57, 41);">一、背景</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">为了保证高可用,之前在测试环境部署了一套 MySQL 双主模式,当一个主库服务出现异常,可以将流量切到另外一个主库,两个主库之间相互同步数据。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;outline: 0px;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.8px;text-align: left;white-space: normal;word-spacing: 0.8px;background-color: rgb(255, 255, 255);color: black;"><span style="outline: 0px;font-size: 16px;color: rgb(34, 34, 34);">双主模式</span></h3> <p data-tool="mdnice编辑器" style="margin-top: 0em;margin-bottom: 0em;padding-top: 8px;padding-bottom: 8px;outline: 0px;color: rgb(53, 53, 53);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: 15px;letter-spacing: 0.8px;text-align: left;white-space: normal;word-spacing: 0.8px;background-color: rgb(255, 255, 255);line-height: 1.75;">双主模式的原理图如下:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;color: rgb(53, 53, 53);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: 15px;letter-spacing: 0.8px;text-align: left;white-space: normal;word-spacing: 0.8px;background-color: rgb(255, 255, 255);display: flex;flex-direction: column;justify-content: center;align-items: center;border-radius: 16px;overflow: hidden;"> <img class="rich_pages wxw-img" data-ratio="1.1875" src="/upload/1b295264f85f14bb4537252059453926.png" data-type="png" data-w="896" style="margin: 20px auto;outline: 0px;border-radius: 6px;display: block;object-fit: contain;box-sizing: border-box !important;visibility: visible !important;width: 677px !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">但是经常出现数据冲突的问题,于是我们又把<code style="font-size: 14px;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(255, 93, 108);">双主模式</code>改为了<code style="font-size: 14px;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(255, 93, 108);">主从读写分离模式</code>。主库作为读写库,再加上一个从库用来做 <span style="font-weight: 700;color: rgb(248, 57, 41);">I/O 密集型</span>的任务(如大量的数据统计操作)。如下图所示:</p> <p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.4051094890510949" data-s="300,640" src="/upload/1072b014bfb26c8c7efbe65154eef4eb.png" data-type="png" data-w="1096" style=""></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">另外从库复制的模式采用<code style="font-size: 14px;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(255, 93, 108);">位点</code>的方式:指定 binlog 文件和 binlog 位置,这样从库就知道了复制的起始位置。(下文会讲解这种方式)</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;"><span style="font-weight: 700;color: rgb(248, 57, 41);">虽然改为了主从模式,但依旧遇到了些问题:</span></p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: rgb(248, 57, 41);font-size: 16px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> <span style="font-weight: 700;color: rgb(248, 57, 41);">问题 1</span>:从库 B 复制数据时,出现了主键冲突问题,导致同步失败,从库停止复制。猜测因主库配置的 binlog 日志的格式为 <code style="font-size: 14px;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(255, 93, 108);">mixed</code>,从库同步时出现不一致的情况。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> <span style="font-weight: 700;color: rgb(248, 57, 41);">问题 2</span>:从库 B 停止复制后,导致很多数据未同步到从库,出现主从大量数据不一致的情况。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> <span style="font-weight: 700;color: rgb(248, 57, 41);">问题 3</span>:从库 B 想要恢复复制,必须先解决同步失败的问题才能恢复。排查难度较大,耗时。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> <span style="font-weight: 700;color: rgb(248, 57, 41);">问题 4</span>:从库 B 恢复时,必须知道同步 <span style="font-weight: 700;color: rgb(248, 57, 41);">位点</span>,也就是从哪个 binlog 文件和 binlog 位置断开复制的,且即使找到了位点,也不是精确的。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> <span style="font-weight: 700;color: rgb(248, 57, 41);">问题 5</span>:从库 B 因同步异常导致停止复制到恢复复制这段期间,主库 A 自动清理了几天前的 binlog 日志,而这些日志从库 B 还未来得及同步,进而导致再次同步失败。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> <span style="font-weight: 700;color: rgb(248, 57, 41);">问题 6</span>:主从存在同步延迟。 </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">这篇我们来探讨下问题 4 和问题 6。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">其中<strong>问题 4</strong> 是一个比较头疼的问题,我们一般是通过查看从库 B 当前的同步状态拿到同步位点,然后设置同步位点后。但是重新启动同步的时候又会出现同步异常,比如从库 B 可能会出现 Duplicate entry ‘id_of_R’ for key ‘PRIMARY’ 错误,提示出现了主键冲突,然后停止同步。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">为了减少位点同步引入的复杂度,我们切换成了 GTID 模式。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">对于<strong>问题 6</strong>,本篇也仅限于探讨如何观察延迟,对于如何减少延迟不在本篇探讨范围之内。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">接下来我们来展开看下位点同步的痛点。</p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 22px;margin-top: 20px;margin-right: 10px;"><span style="display: none;"></span><span style="font-size: 18px;color: rgb(34, 34, 34);display: inline-block;padding-left: 10px;border-left: 5px solid rgb(248, 57, 41);">二、位点同步的痛点</span></h2> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 20px;"><span style="display: none;"></span><span style="font-size: 16px;color: #222;">2.1 通过位点同步的原理图</span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">为了更清晰地理解主从采用位点同步的原理,这里有一个原理图:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;border-radius: 16px;overflow: hidden;"> <img class="rich_pages wxw-img" data-ratio="1.0513761467889908" src="/upload/8cdc0270f641a564c3a3e7f6f21a85b3.png" data-type="png" data-w="1090" style="border-radius: 6px;display: block;margin: 20px auto;max-width: 95%;object-fit: contain;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;"><strong>1、</strong>主库会生成多个 binlog 日志文件。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;"><strong>2、</strong>从库的I/O 线程请求指定文件和指定位置的 binlog 日志文件(位点)。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;"><strong>3、</strong>主库 dump 线程获取指定位点的 binlog 日志。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;"><strong>4、</strong>主库按照从库发送给来的位点信息读取 binlog,然后推送 binlog 给从库。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;"><strong>5、</strong>从库将得到的 binlog 写到本地的 relay log (中继日志) 文件中。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;"><strong>6、</strong>从库的 SQL 线程读取和解析 relay log 文件。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;"><strong>7、</strong>从库的 SQL 线程重放 relay log 中的命令。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">当我们使用位点同步的方式时,两种场景下的操作步骤比较复杂。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 20px;"><span style="display: none;"></span><span style="font-size: 16px;color: #222;">2.2 痛点</span><span style="display: none;"></span></h3> <h4 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 18px;"><span style="display: none;"></span><span style="font-size: 15px;color: #222;">痛点1:首次开启主从复制的步骤复杂</span><span style="display: none;"></span></h4> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: rgb(248, 57, 41);font-size: 16px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 第一次开启主从同步时,要求从库和主库是一致的。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 找到主库的 binlog 位点。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 设置从库的 binlog 位点。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 开启从库的复制线程。 </section></li> </ul> <h4 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 18px;"><span style="display: none;"></span><span style="font-size: 15px;color: #222;">痛点2:恢复主从复制的步骤复杂</span><span style="display: none;"></span></h4> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: rgb(248, 57, 41);font-size: 16px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 找到从库复制线程停止时的位点。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 解决复制异常的事务。无法解决时就需要手动跳过指定类型的错误,比如通过设置slave_skip_errors=1032,1062。当然这个前提条件是跳过这类错误是无损的。(1062 错误是插入数据时唯一键冲突;1032 错误是删除数据时找不到行) </section></li> </ul> <blockquote data-tool="mdnice编辑器" style="border-top: none;border-right: none;border-bottom: none;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(255, 177, 27);background: rgb(255, 245, 227);"> <p style="padding-top: 8px;padding-bottom: 8px;font-size: 15px;color: black;line-height: 26px;">不论是首次开启同步时需要找位点和设置位点,还是恢复主从复制时,设置位点和忽略错误,<span style="font-weight: 700;color: rgb(248, 57, 41);">这些步骤都显得过于复杂,而且容易出错</span>。所以 MySQL 5.6 版本引入了 GTID,彻底解决了这个困难。</p> </blockquote> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 22px;margin-top: 20px;margin-right: 10px;"><span style="display: none;"></span><span style="font-size: 18px;color: rgb(34, 34, 34);display: inline-block;padding-left: 10px;border-left: 5px solid rgb(248, 57, 41);">三、GTID 方案</span></h2> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 20px;"><span style="display: none;"></span><span style="font-size: 16px;color: #222;">3.1 GTID 是什么?</span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">GTID 的全称是 Global Transaction Identifier,全局事务 ID,当一个事务提交时,就会生成一个 GTID,相当于事务的唯一标识。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">GTID 长这样:</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="display: block;background: url(&quot;https://mmbiz.qpic.cn/mmbiz_svg/ibKHP1TZZeXL1oiaVUBdfxCY6LwIw0EwxwOIRLYDKbuuMHDiaLZiakGTibpibXeKuverExaBHKbvOBXyhICblxHNrnYo3iaYicbrw4xw/640?wx_fmt=svg&quot;) 10px 10px / 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #282c34;border-radius: 5px;">c5d74746-d7ec-11ec-bf8f-0242ac110002:1<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">结构:</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="display: block;background: url(&quot;https://mmbiz.qpic.cn/mmbiz_svg/ibKHP1TZZeXL1oiaVUBdfxCY6LwIw0EwxwOIRLYDKbuuMHDiaLZiakGTibpibXeKuverExaBHKbvOBXyhICblxHNrnYo3iaYicbrw4xw/640?wx_fmt=svg&quot;) 10px 10px / 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #282c34;border-radius: 5px;">GTID=server_uuid:gno<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">server_uuid 是一个实例第一次启动时自动生成的,是一个全局唯一的值;</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">gno 是一个整数,初始值是 1,每次提交事务的时候分配给这个事务,并加 1。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">每个 MySQL 实例都维护了一个 GTID 集合,用来对应“这个实例执行过的所有事务”。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;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.8px;text-align: left;white-space: normal;word-spacing: 0.8px;background-color: rgb(255, 255, 255);color: black;"><span style="font-size: 16px;color: rgb(34, 34, 34);">3.2 GTID 的优势</span></h3> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="line-height: 1.6;word-break: break-word;text-align: left;font-size: 15px;color: rgb(53, 53, 53);word-spacing: 0.8px;letter-spacing: 0.8px;border-radius: 16px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;"> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: rgb(248, 57, 41);font-size: 16px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;font-size: 15px;">1、更简单的实现 failover,不用以前那样在需要找位点(log_file 和 log_pos)。</p> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;font-size: 15px;">2、更简单的搭建主从复制。</p> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;font-size: 15px;">3、比传统的复制更加安全。</p> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;font-size: 15px;">4、GTID是连续的没有空洞的,保证数据的一致性,零丢失。<span style="letter-spacing: 0.8px;word-spacing: 0.8px;"></span></p> </section></li> </ul> </section> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 20px;"><span style="display: none;"></span><span style="font-size: 16px;color: #222;">3.3 如何启用 GTID</span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">修改主库和从库的配置文件:</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="display: block;background: url(&quot;https://mmbiz.qpic.cn/mmbiz_svg/ibKHP1TZZeXL1oiaVUBdfxCY6LwIw0EwxwOIRLYDKbuuMHDiaLZiakGTibpibXeKuverExaBHKbvOBXyhICblxHNrnYo3iaYicbrw4xw/640?wx_fmt=svg&quot;) 10px 10px / 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #282c34;border-radius: 5px;"><span style="color: #5c6370;font-style: italic;line-height: 26px;">#GTID:</span><br>gtid_mode=on<br>enforce_gtid_consistency=on<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">从库配置同步的参数:</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="display: block;background: url(&quot;https://mmbiz.qpic.cn/mmbiz_svg/ibKHP1TZZeXL1oiaVUBdfxCY6LwIw0EwxwOIRLYDKbuuMHDiaLZiakGTibpibXeKuverExaBHKbvOBXyhICblxHNrnYo3iaYicbrw4xw/640?wx_fmt=svg&quot;) 10px 10px / 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #282c34;border-radius: 5px;">CHANGE&nbsp;MASTER&nbsp;TO&nbsp;<br>MASTER_HOST=<span style="color: #d19a66;line-height: 26px;">$host_name</span>&nbsp;<br>MASTER_PORT=<span style="color: #d19a66;line-height: 26px;">$port</span>&nbsp;<br>MASTER_USER=<span style="color: #d19a66;line-height: 26px;">$user_name</span>&nbsp;<br>MASTER_PASSWORD=<span style="color: #d19a66;line-height: 26px;">$password</span>&nbsp;<br>master_auto_position=1&nbsp;<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">其中 master_auto_position 标识主从关系使用的 GTID 协议。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">相比之前的配置,<span style="font-weight: 700;color: rgb(248, 57, 41);">MASTER_LOG_FILE 和 MASTER_LOG_POS 参数已经不需要了</span>。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 20px;"><span style="display: none;"></span><span style="font-size: 16px;color: #222;">3.4 GTID 同步方案</span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">GTID 同步的原理图。</p> <blockquote data-tool="mdnice编辑器" style="border-top: none;border-right: none;border-bottom: none;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(255, 177, 27);background: rgb(255, 245, 227);"> <p style="padding-top: 8px;padding-bottom: 8px;font-size: 15px;color: black;line-height: 26px;"><span style="font-weight: 700;color: rgb(248, 57, 41);">GTID 方案</span>:主库计算主库 GTID 集合和从库 GTID 的集合的差集,主库推送差集 binlog 给从库。</p> </blockquote> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">当从库设置完同步参数后,主库 A 的GTID 集合记为集合 x,从库 B 的 GTID 集合记为 y。从库同步的逻辑如下:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;border-radius: 16px;overflow: hidden;"> <img class="rich_pages wxw-img" data-ratio="1.0510046367851622" src="/upload/3e95be8ed3f7eb9a644a897d3bfe50cb.png" data-type="png" data-w="1294" style="border-radius: 6px;display: block;margin: 20px auto;max-width: 95%;object-fit: contain;"> </figure> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: rgb(248, 57, 41);font-size: 16px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 从库 B 指定主库 A,基于主备协议简历连接。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 从库 B 把集合 y 发给主库 A。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 主库 A 计算出集合 x 和集合 y 的差集,也就是集合 x 中存在,集合 y 中不存在的 GTID 集合。比如集合 x 是 1~100,集合 y 是 1~90,那么这个差集就是 91~100。这里会判断集合 x 是不是包含有集合 y 的所有 GTID,如果不是则说明主库 A 删除了从库 B 需要的 binlog,主库 A 直接返回错误。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 主库 A 从自己的 binlog 文件里面,找到第一个不在集合 y 中的事务 GTID,也就是找到了 91。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 主库 A 从 GTID = 91 的事务开始,往后读 binlog 文件,按顺序取 binlog,然后发给 B。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 从库 B 的 I/O 线程读取 binlog 文件生成 relay log,SQL 线程解析 relay log,然后执行 SQL 语句。 </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;"><strong>GTID 同步方案和位点同步的方案区别是:</strong></p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: rgb(248, 57, 41);font-size: 16px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 位点同步方案是通过人工在从库上指定哪个位点,主库就发哪个位点,不做日志的完整性判断。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> 而 GTID 方案是通过主库来自动计算位点的,不需要人工去设置位点,对运维人员友好。 </section></li> </ul> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 22px;margin-top: 20px;margin-right: 10px;"><span style="display: none;"></span><span style="font-size: 18px;color: rgb(34, 34, 34);display: inline-block;padding-left: 10px;border-left: 5px solid rgb(248, 57, 41);">四、如何判断主从库是否有延迟</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">上面提到的问题 6 是主从读写分离后,从库复制存在延迟,接下来我们来探讨下如何观察主从延迟多少的问题。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">方案一:判断从库的同步状态参数 seconds_behind_master 是否为 0。(不准确)</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">方案二:对比位点确保主备无延迟。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">方案三:对比 GTID 集合确保主备无延迟。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 20px;"><span style="display: none;"></span><span style="font-size: 16px;color: #222;">方案一:查看 seconds_behind_master</span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">可以在从库上执行 slow slave status 命令来看执行结果里面的 <code style="font-size: 14px;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(255, 93, 108);">seconds_behind_master</code> 参数的值,如下图所示,Seconds_Behind_Master 等于 0</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;border-radius: 16px;overflow: hidden;"> <img class="rich_pages wxw-img" data-ratio="0.3241252302025783" src="/upload/e6b107d5c2f50752770e92125e5cec76.png" data-type="png" data-w="543" style="border-radius: 6px;display: block;margin: 20px auto;max-width: 95%;object-fit: contain;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">Seconds_Behind_Master 的单位是秒,所以精度不准确。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">所以为了保证查询的数据是和主库一致的,就需要先判断 seconds_behind_master 是否已经等于 0,如果不等于 0,就必须等到这个参数变为 0 才能执行查询请求。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 20px;"><span style="display: none;"></span><span style="font-size: 16px;color: #222;">方案二:对比位点</span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">可以通过查看从库当前的同步位点来确认从库同步是否有延迟。下图是在从库上执行 <code style="font-size: 14px;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(255, 93, 108);">show slave status \G</code>命令后的结果:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;border-radius: 16px;overflow: hidden;"> <img class="rich_pages wxw-img" data-ratio="0.6237288135593221" src="/upload/b3cea0e13b9a34e9091973e8f9910ea4.png" data-type="png" data-w="1180" style="border-radius: 6px;display: block;margin: 20px auto;max-width: 95%;object-fit: contain;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;"><code style="font-size: 14px;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(255, 93, 108);">Master_Log_File</code> 和 <code style="font-size: 14px;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(255, 93, 108);">Read_Master_Log_Pos</code> 这两个参数合起来表示的是读到的主库的最新位点,第一参数是代表读取到了哪个文件,第二个是读取到的文件的位置。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;"><code style="font-size: 14px;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(255, 93, 108);">Relay_Master_Log_File</code> 和 <code style="font-size: 14px;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(255, 93, 108);">Exec_Master_Log_Pos</code>,这两个参数合起来表示的是从库执行的最新位点。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">如果红色框起来的两个参数:<code style="font-size: 14px;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(255, 93, 108);">Master_Log_File</code> 和 <code style="font-size: 14px;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(255, 93, 108);">Relay_Master_Log_File</code> 相等,则说明从库读到的最新文件和主库上生成的文件相同,这里都是 mysql-bin.000934。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">如果蓝色框起来的两个参数 <code style="font-size: 14px;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(255, 93, 108);">Read_Master_Log_Pos</code> 和 <code style="font-size: 14px;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(255, 93, 108);">Exec_Master_Log_Pos</code> 相等,则说明从库读到的日志文件的位置和从库上执行日志文件的位置相同,这里都是 59521082。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">当上面两组参数都相等时,则说明没有延迟。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 20px;"><span style="display: none;"></span><span style="font-size: 16px;color: #222;">方案三:对比 GTID 集合</span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">方案三是对比 GTID 集合。首先我们在从库上执行 &nbsp;<code style="font-size: 14px;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(255, 93, 108);">show slave status \G</code>来查看 GTID 集合。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">如下图所示:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;border-radius: 16px;overflow: hidden;"> <img class="rich_pages wxw-img" data-ratio="0.3654970760233918" src="/upload/5c20fcc6b1777cd57585cf8058cf1f13.png" data-type="png" data-w="1026" style="border-radius: 6px;display: block;margin: 20px auto;max-width: 95%;object-fit: contain;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;"><code style="font-size: 14px;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(255, 93, 108);">Master_UUID</code> 表示当前连接的主库的 ID。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;"><code style="font-size: 14px;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(255, 93, 108);">Auto_Position</code>: 1 表示主备使用了 GTID 协议。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;"><code style="font-size: 14px;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(255, 93, 108);">Retrieved_Gtid_Set</code> 表示从库收到的所有日志的 GTID 集合。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;"><code style="font-size: 14px;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(255, 93, 108);">Executed_Gtid_Set</code> 表示从库已经执行完成的 GTID 集合。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">如果 Executed_Gtid_Set 集合是包含 Retrieved_Gtid_Set,则表示从库接收到的日志已经同步完成。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">比如上图中 <code style="font-size: 14px;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(255, 93, 108);">Retrieved_Gtid_Set</code> 值为</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="display: block;background: url(&quot;https://mmbiz.qpic.cn/mmbiz_svg/ibKHP1TZZeXL1oiaVUBdfxCY6LwIw0EwxwOIRLYDKbuuMHDiaLZiakGTibpibXeKuverExaBHKbvOBXyhICblxHNrnYo3iaYicbrw4xw/640?wx_fmt=svg&quot;) 10px 10px / 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #282c34;border-radius: 5px;">c5d74746-d7ec-11ec-bf8f-0242ac110002:1-87323<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">前面一段是主库 id,后面一段 1-87383 是 GTID 范围。而<code style="font-size: 14px;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(255, 93, 108);">Executed_Gtid_Set</code> 的值有两个集合</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="display: block;background: url(&quot;https://mmbiz.qpic.cn/mmbiz_svg/ibKHP1TZZeXL1oiaVUBdfxCY6LwIw0EwxwOIRLYDKbuuMHDiaLZiakGTibpibXeKuverExaBHKbvOBXyhICblxHNrnYo3iaYicbrw4xw/640?wx_fmt=svg&quot;) 10px 10px / 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #282c34;border-radius: 5px;">7083ae1f-d7ef-11ec-a329-0242ac110002:1-2,<br>c5d74746-d7ec-11ec-bf8f-0242ac110002:1-87323<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;"><code style="font-size: 14px;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(255, 93, 108);">Executed_Gtid_Set</code> 的第二个集合和第一个集合完全一致,第一个集合 id 和 集合范围是上次同步另外一个主库的记录。这里说明从库已经和当前主库同步完成了。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">方案二对比位点和方案三的 GTID 比对都要比方案一的<code style="font-size: 14px;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(255, 93, 108);">seconds_behind_master</code> 更准确。但是还是没有达到精确的程度,需要配合半同步复制(semi-sync replication)才能达到。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">小结:本篇通过 GTID 的方式更好地实现了主从节点的同步,以及如何观察主从同步的延迟。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">参考资料:</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">www.passjava.cn</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">https://time.geekbang.org/column/article/77636</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">高性能 MySQL 第四版</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0em;margin-bottom: 0em;">千金良方:MySQL性能优化金字塔法则</p> </section> </section>

月增千万的数据,我用单体+单库扛下了所有~

作者:微信小助手

<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="line-height: 1.6;word-break: break-word;text-align: left;padding: 5px;font-size: 16px;color: rgb(53, 53, 53);word-spacing: 0.8px;letter-spacing: 0.8px;border-radius: 16px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;" data-mpa-powered-by="yiban.io"> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">分库分表实战内容基本上很少有人去分享,在网上能够搜出来的也大多属于一些方法论,但大部分技术开发真正缺少的恰恰是这些实操经验,所以后续的内容多以实践为主,携手诸位真正彻底悟透分库分表相关的技术。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">尤其是对于库内分表这块的分享,当你去搜索单表数据增长过快该如何处理时,一般都会推荐你做分表处理,但你几乎找不到较为全面的实操教学,网上讲述分表技术更多是停留在表面的理论概念层次做阐述,而本章中则会结合自身之前接触的一个项目业务,再对库内分表技术进行全面阐述~</p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 22px;margin-top: 20px;margin-right: 10px;"><span style="display: none;"></span><span style="font-size: 18px;color: rgb(234, 84, 41);letter-spacing: 0.5444px;padding-bottom: 10px;border-bottom: 2px solid rgb(234, 84, 41);visibility: visible;">1. 源自于软硬结合的特殊业务</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">在讲本次主题之前,先来聊聊之前碰到的这个业务,这个业务比较特殊,相信很多小伙伴从未碰到过,这种业务本身用户量大,甚至可以说用户量非常非常少,因为业务的起源来自于一款硬件设备,但具体的设备类型由于某些缘故就不透露了,可以理解成是下面这个东东:<img class="rich_pages wxw-img" data-ratio="0.8947368421052632" src="/upload/c4b9081c493be3da4c4cfec6113212c5.jpg" data-type="jpeg" data-w="741" style="border-radius: 6px;display: block;margin: 20px auto;max-width: 95%;object-fit: contain;">虽然当时的硬件设备并不是这个,但也和它很类似,相信大家但凡在超市购过物都认识它,也就是超市收银台的收银机,当时我们是对外提供了一千台设备,这种设备通常一台只有一个用户,所以当时整个系统上线后所有的用户加起来,涵盖后台管理员、超级管理员账号在内,也不过<code style="font-size: 14px;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(255, 93, 108);">1200</code>个用户,这个用户规模相较于常见业务而言属实不多。</p> <blockquote data-tool="mdnice编辑器" style="border-top: none;border-right: none;border-bottom: none;font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);border-left-width: 2px;padding: 8px 10px 8px 15px;background: rgb(255, 249, 249);border-left-color: rgb(239, 112, 96);margin-top: 0px;margin-bottom: 20px;letter-spacing: 0.5444px;"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(53, 53, 53);font-size: 16px;margin-right: 10px;margin-left: 10px;">而当时我们需要负责的就是:为这些设备开发一个操作系统,这里不是指<code style="font-size: 14px;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(255, 93, 108);">Windows、Linux、Mac</code>这类嵌入式的底层系统,而是给机器的操作员开发一个操作界面,就类似于诸位在超市购物时,超市收银员用手操作的那个界面。</p> </blockquote> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">因为这些机器本身会安装一个带<code style="font-size: 14px;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(255, 93, 108);">UI</code>的系统,里面也支持安装一些软件,我们的软件会以<code style="font-size: 14px;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(255, 93, 108);">GUI</code>的形式嵌入这些设备,当时我要干的就是直接开发<code style="font-size: 14px;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(255, 93, 108);">API</code>接口,然后提供给<code style="font-size: 14px;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(255, 93, 108);">GUI</code>界面界面调用。本质上就属一个前后端分离的项目,只不过前端从原本的<code style="font-size: 14px;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(255, 93, 108);">Web</code>界面变成了<code style="font-size: 14px;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(255, 93, 108);">GUI</code>界面。</p> <blockquote data-tool="mdnice编辑器" style="border-top: none;border-right: none;border-bottom: none;font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);border-left-width: 2px;padding: 8px 10px 8px 15px;background: rgb(255, 249, 249);border-left-color: rgb(239, 112, 96);margin-top: 0px;margin-bottom: 20px;letter-spacing: 0.5444px;"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(53, 53, 53);font-size: 16px;margin-right: 10px;margin-left: 10px;">大家听起来这个项目是不是特别容易完成,用户量又少代表不需要考虑并发,也不会存在太大的流量冲击,性能要求也不会太高,似乎就是一个简简单单的单体增删改查项目呀?但事情远没有表面这么简单,诸位请接着往下看。</p> </blockquote> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 20px;"><span style="display: none;"></span><span style="font-size: 16px;color: #222;">1.1、项目的难点</span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">起初当我收到通知要负责这个需求时,从表面浅显的想了一下,似乎发现也不是太难,就是一个单体项目的<code style="font-size: 14px;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(255, 93, 108);">CRUD</code>工作,以我这手出神入化的<code style="font-size: 14px;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(255, 93, 108);">CV</code>大法,<code style="font-size: 14px;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(255, 93, 108);">Hlod</code>住它简直轻轻松松,因此当时也没想太多就直接接手了,项目初期由于团队每位成员经验都很丰富,各自凭借着个人的<code style="font-size: 14px;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(255, 93, 108);">Copy</code>神功,项目的开发进度可谓是一骑千里,但慢慢的问题来了,而且这个问题还不小!</p> <blockquote data-tool="mdnice编辑器" style="border-top: none;border-right: none;border-bottom: none;font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);border-left-width: 2px;padding: 8px 10px 8px 15px;background: rgb(255, 249, 249);border-left-color: rgb(239, 112, 96);margin-top: 0px;margin-bottom: 20px;letter-spacing: 0.5444px;"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(53, 53, 53);font-size: 16px;margin-right: 10px;margin-left: 10px;">当时大概对外预计分发<code style="font-size: 14px;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(255, 93, 108);">1000</code>台机器,每台机器正式投入运营后,预估单日会产生<code style="font-size: 14px;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(255, 93, 108);">500~600</code>条数据的产出,套到前面的举例中,也就是大概会向几百个超市投放共计<code style="font-size: 14px;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(255, 93, 108);">1000</code>台收银机,每个收银台平均下来之后,大概单日内会有<code style="font-size: 14px;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(255, 93, 108);">500~600</code>个顾客结账!</p> </blockquote> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">这里咱们做个数学题:现在有<code style="font-size: 14px;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(255, 93, 108);">1000</code>台机器,每台机器单日就算产生<code style="font-size: 14px;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(255, 93, 108);">500</code>条数据:<code style="font-size: 14px;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(255, 93, 108);">1000 * 500 = 500000</code>,这也就意味着单日的账单表中会新增<code style="font-size: 14px;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(255, 93, 108);">50W</code>条流水数据,单月整个账单表的数据增长量为:<code style="font-size: 14px;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(255, 93, 108);">50W * 30 = 1500W</code>!</p> <blockquote data-tool="mdnice编辑器" style="border-top: none;border-right: none;border-bottom: none;font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);border-left-width: 2px;padding: 8px 10px 8px 15px;background: rgb(255, 249, 249);border-left-color: rgb(239, 112, 96);margin-top: 0px;margin-bottom: 20px;letter-spacing: 0.5444px;"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(53, 53, 53);font-size: 16px;margin-right: 10px;margin-left: 10px;">单月数据增长<code style="font-size: 14px;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(255, 93, 108);">1500W</code>的概念不言而喻,这也就代表着一年的数据增长量为<code style="font-size: 14px;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(255, 93, 108);">1500W * 12 = 1.8E</code>,这批机器投入后预估最少会运行三年起步,甚至十年乃至更久,同时第一批次就要投入<code style="font-size: 14px;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(255, 93, 108);">1000</code>台,后面可能还会有第二批次、第三批次.....的投入。</p> </blockquote> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;"><code style="font-size: 14px;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(255, 93, 108);">50W</code>只是最低的账单流水数据量,后续正式运营后可能数据量更大,此时架构的设计就成了难题!</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 20px;"><span style="display: none;"></span><span style="font-size: 16px;color: #222;">1.2、方案的探讨</span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">基本上当时团队的成员中,没人在此之前碰过这类需求,因此开了一个研讨会,去决定该如何将具体的方案落地,这里有人也许会说,数据量这么大,快上分布式/微服务啊!但实则解决不了这个问题,<code style="font-size: 14px;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(255, 93, 108);">Why</code>?因为项目整体的用户量并不大,最多同一时刻也才<code style="font-size: 14px;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(255, 93, 108);">1000</code>并发请求,就算这个并发量再增大几个级别,这里用单体架构优化好了也能够抗住,所以问题并不在业务系统的架构上面,而是在数据落库这方面。</p> <blockquote data-tool="mdnice编辑器" style="border-top: none;border-right: none;border-bottom: none;font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);border-left-width: 2px;padding: 8px 10px 8px 15px;background: rgb(255, 249, 249);border-left-color: rgb(239, 112, 96);margin-top: 0px;margin-bottom: 20px;letter-spacing: 0.5444px;"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(53, 53, 53);font-size: 16px;margin-right: 10px;margin-left: 10px;">这里直接用分库可以吗?答案是也不行,<code style="font-size: 14px;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(255, 93, 108);">Why</code>?因为整个项目中只有账单表才有这么大的数据量,其他的用户表、系统表、功能菜单表、后台表......,基本上不会有太大的数据量,所以直接做分库也没必要,属实有些浪费资源。</p> </blockquote> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">有小伙伴可能想到了!在之前的文章中好像聊过《MySQL的表分区技术》,这里可以按月份对流水表做分区呀!乍一听似乎像那么一回事,但依旧不行,因为第一批机器投入后,单月预计就会产生<code style="font-size: 14px;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(255, 93, 108);">1500W</code>条数据,后续可能会增加机器数量,因此单月的数据量达到<code style="font-size: 14px;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(255, 93, 108);">2000W、3000W.....</code>都有可能,如果按月做表分区,每个分区里面都有几千万条数据,一张账单表的流水随着时间推移,数据量甚至会达到几十亿!</p> <blockquote data-tool="mdnice编辑器" style="border-top: none;border-right: none;border-bottom: none;font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);border-left-width: 2px;padding: 8px 10px 8px 15px;background: rgb(255, 249, 249);border-left-color: rgb(239, 112, 96);margin-top: 0px;margin-bottom: 20px;letter-spacing: 0.5444px;"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(53, 53, 53);font-size: 16px;margin-right: 10px;margin-left: 10px;">一张表中存储几十亿条数据,这基本上不现实,虽然<code style="font-size: 14px;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(255, 93, 108);">InnoDB</code>在数据页为<code style="font-size: 14px;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(255, 93, 108);">16KB</code>尺寸下,单表最多能存储<code style="font-size: 14px;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(255, 93, 108);">64TB</code>数据,有可能这几十亿条数据真的能存下去,但查询时的性能简直令人头大,并且最关键的是不方便后续对数据做维护、管理、备份和迁移工作。</p> </blockquote> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">因此经过一番探讨后,最后决定选择了表分区技术的进阶版实现,即单库内做水平分表,按月份对数据做分表,也就是将账单表分为<code style="font-size: 14px;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(255, 93, 108);">month_bills_202210、month_bills_202211、month_bills_202212.......</code>以月份结尾的多张表,每个月的账单流水数据最终都会插入到各自的月份表中。</p> <blockquote data-tool="mdnice编辑器" style="border-top: none;border-right: none;border-bottom: none;font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);border-left-width: 2px;padding: 8px 10px 8px 15px;background: rgb(255, 249, 249);border-left-color: rgb(239, 112, 96);margin-top: 0px;margin-bottom: 20px;letter-spacing: 0.5444px;"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(53, 53, 53);font-size: 16px;margin-right: 10px;margin-left: 10px;">最终架构定型为:<span style="font-weight: 700;color: rgb(248, 57, 41);">业务系统使用单体架构 + 数据库使用单库 + 流水表按月份做水平分表。</span></p> </blockquote> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 22px;margin-top: 20px;margin-right: 10px;"><span style="display: none;"></span><span style="font-size: 18px;color: rgb(234, 84, 41);letter-spacing: 0.5444px;padding-bottom: 10px;border-bottom: 2px solid rgb(234, 84, 41);visibility: visible;">2. &nbsp;按月分表方案的落地实践</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">在上一阶段中已经决定好了具体的方案,但又该如何将方案落地呢?首先咱们先把方案落地的思路捋清楚:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: rgb(248, 57, 41);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> ①能够自动按月创建一张月份账单表,从而将每月的流水数据写入进去。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> ②写入数据时,能够根据当前的日期,选择对应的月份账单表并插入数据。 </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">实现了上面两个需求后,整个方案近乎落地了一半,但接下来该如何去实现相应功能呢?咱们一点点来动手实现。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;color: black;font-size: 20px;"><span style="display: none;"></span><span style="font-size: 16px;color: #222;">2.1、利用存储过程实现按月动态创建表</span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">创建表的<code style="font-size: 14px;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(255, 93, 108);">SQL</code>语句大家都不陌生,按月份创建表之前,自然也需要一份原生创建表的<code style="font-size: 14px;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(255, 93, 108);">DDL</code>语句,如下:</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="display: block;background: url(&quot;https://mmbiz.qpic.cn/mmbiz_svg/A7sq8BD8oezBibiciavS1eDQVpKdKQvg6wWj5ASkJmxWV4umyR2wB45aPZpW6R8zcJiaUXoFmIxXGVuXjnKyKk2bmV244xlc0mtq/640?wx_fmt=svg&quot;) 10px 10px / 40px no-repeat rgb(255, 255, 255);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: black;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #fff;border-radius: 5px;"><span style="color: #aa0d91;line-height: 26px;">CREATE</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">TABLE</span>&nbsp;<span style="color: #c41a16;line-height: 26px;">`month_bills_202211`</span>&nbsp;&nbsp;(<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #c41a16;line-height: 26px;">`month_bills_id`</span>&nbsp;<span style="color: #5c2699;line-height: 26px;">int</span>(<span style="color: #1c00cf;line-height: 26px;">8</span>)&nbsp;<span style="color: #aa0d91;line-height: 26px;">NOT</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">NULL</span>&nbsp;AUTO_INCREMENT&nbsp;<span style="color: #aa0d91;line-height: 26px;">COMMENT</span>&nbsp;<span style="color: #c41a16;line-height: 26px;">'账单ID'</span>,<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #c41a16;line-height: 26px;">`serial_number`</span>&nbsp;<span style="color: #5c2699;line-height: 26px;">varchar</span>(<span style="color: #1c00cf;line-height: 26px;">50</span>)&nbsp;<span style="color: #aa0d91;line-height: 26px;">NOT</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">NULL</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">COMMENT</span>&nbsp;<span style="color: #c41a16;line-height: 26px;">'流水号'</span>,<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #c41a16;line-height: 26px;">`bills_info`</span>&nbsp;<span style="color: #5c2699;line-height: 26px;">text</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">NOT</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">NULL</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">COMMENT</span>&nbsp;<span style="color: #c41a16;line-height: 26px;">'账单详情'</span>,<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #c41a16;line-height: 26px;">`pay_money`</span>&nbsp;<span style="color: #5c2699;line-height: 26px;">decimal</span>(<span style="color: #1c00cf;line-height: 26px;">10</span>,<span style="color: #1c00cf;line-height: 26px;">3</span>)&nbsp;<span style="color: #aa0d91;line-height: 26px;">NOT</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">NULL</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">COMMENT</span>&nbsp;<span style="color: #c41a16;line-height: 26px;">'支付金额'</span>,<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #c41a16;line-height: 26px;">`machine_serial_no`</span>&nbsp;<span style="color: #5c2699;line-height: 26px;">varchar</span>(<span style="color: #1c00cf;line-height: 26px;">20</span>)&nbsp;<span style="color: #aa0d91;line-height: 26px;">NOT</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">NULL</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">COMMENT</span>&nbsp;<span style="color: #c41a16;line-height: 26px;">'收银机器'</span>,<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #c41a16;line-height: 26px;">`bill_date`</span>&nbsp;<span style="color: #5c2699;line-height: 26px;">timestamp</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">NOT</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">NULL</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">COMMENT</span>&nbsp;<span style="color: #c41a16;line-height: 26px;">'账单日期'</span>,<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #c41a16;line-height: 26px;">`bill_comment`</span>&nbsp;<span style="color: #5c2699;line-height: 26px;">varchar</span>(<span style="color: #1c00cf;line-height: 26px;">100</span>)&nbsp;<span style="color: #aa0d91;line-height: 26px;">NULL</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">DEFAULT</span>&nbsp;<span style="color: #c41a16;line-height: 26px;">'无'</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">COMMENT</span>&nbsp;<span style="color: #c41a16;line-height: 26px;">'账单备注'</span>,<br>&nbsp;&nbsp;&nbsp;&nbsp;PRIMARY&nbsp;<span style="color: #aa0d91;line-height: 26px;">KEY</span>&nbsp;(<span style="color: #c41a16;line-height: 26px;">`month_bills_id`</span>)&nbsp;<span style="color: #aa0d91;line-height: 26px;">USING</span>&nbsp;BTREE,<br>&nbsp;<span style="color: #aa0d91;line-height: 26px;">UNIQUE</span>&nbsp;<span style="color: #c41a16;line-height: 26px;">`serial_number`</span>&nbsp;(<span style="color: #c41a16;line-height: 26px;">`serial_number`</span>),<br>&nbsp;<span style="color: #aa0d91;line-height: 26px;">KEY</span>&nbsp;<span style="color: #c41a16;line-height: 26px;">`bill_date`</span>&nbsp;(<span style="color: #c41a16;line-height: 26px;">`bill_date`</span>)<br>)<br><span style="color: #aa0d91;line-height: 26px;">ENGINE</span>&nbsp;=&nbsp;<span style="color: #aa0d91;line-height: 26px;">InnoDB</span>&nbsp;<br><span style="color: #5c2699;line-height: 26px;">CHARACTER</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">SET</span>&nbsp;=&nbsp;utf8&nbsp;<br><span style="color: #aa0d91;line-height: 26px;">COLLATE</span>&nbsp;=&nbsp;utf8_general_ci&nbsp;<br>ROW_FORMAT&nbsp;=&nbsp;<span style="color: #aa0d91;line-height: 26px;">Compact</span>;<br><br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">上述的语句会创建一张月份账单表,这张表主要包含七个字段,如下:</p> <section data-tool="mdnice编辑器" style="overflow-x: auto;"> <table> <thead> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <th style="border-top-width: 1px;border-color: rgb(204, 204, 204);text-align: left;background-color: rgb(219, 217, 216);min-width: 85px;">字段</th> <th style="border-top-width: 1px;border-color: rgb(204, 204, 204);text-align: left;background-color: rgb(219, 217, 216);min-width: 85px;">简介</th> <th style="border-top-width: 1px;border-color: rgb(204, 204, 204);text-align: left;background-color: rgb(219, 217, 216);min-width: 85px;">描述</th> </tr> </thead> <tbody style="border-width: 0px;border-style: initial;border-color: initial;"> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;"><code>month_bills_id</code></td> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;">月份账单ID</td> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;">主要作为月份账单表的主键字段</td> </tr> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: rgb(248, 248, 248);"> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;"><code>serial_number</code></td> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;">流水号</td> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;">所有账单流水数据的唯一流水号</td> </tr> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;"><code>bills_info</code></td> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;">账单详情</td> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;">顾客本次订单中,购买的所有商品详情数据</td> </tr> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: rgb(248, 248, 248);"> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;"><code>pay_money</code></td> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;">支付金额</td> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;">本次顾客共计消费的总金额</td> </tr> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;"><code>machine_serial_no</code></td> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;">收银机器</td> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;">负责结算顾客订单的收银机器</td> </tr> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: rgb(248, 248, 248);"> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;"><code>bill_date</code></td> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;">账单日期</td> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;">本次账单的结算日期</td> </tr> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;"><code>bill_comment</code></td> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;">账单备注</td> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;">账单的额外备注</td> </tr> </tbody> </table> </section> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">其中注意的几个小细节:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: rgb(248, 57, 41);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> ①日期字段使用的是 <code style="font-size: 14px;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(255, 93, 108);">timestamp</code>类型,而并非 <code style="font-size: 14px;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(255, 93, 108);">datetime</code>,因为前者更省空间。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> ②账单详情字段用的是 <code style="font-size: 14px;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(255, 93, 108);">text</code>类型,因为这个字段可能会出现很多的信息。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(53, 53, 53);"> ③定义了一个和表没有关系的自增字段作为主键,用于维护聚簇索引树的结构。 </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">除开有上述七个字段外,还有三个索引:</p> <section data-tool="mdnice编辑器" style="overflow-x: auto;"> <table> <thead> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <th style="border-top-width: 1px;border-color: rgb(204, 204, 204);text-align: left;background-color: rgb(219, 217, 216);min-width: 85px;">索引字段</th> <th style="border-top-width: 1px;border-color: rgb(204, 204, 204);text-align: left;background-color: rgb(219, 217, 216);min-width: 85px;">索引类型</th> <th style="border-top-width: 1px;border-color: rgb(204, 204, 204);text-align: left;background-color: rgb(219, 217, 216);min-width: 85px;">索引作用</th> </tr> </thead> <tbody style="border-width: 0px;border-style: initial;border-color: initial;"> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;"><code>month_bills_id</code></td> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;">主键索引</td> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;">主要作用就是用来维护聚簇索引树</td> </tr> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: rgb(248, 248, 248);"> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;"><code>serial_number</code></td> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;">唯一索引</td> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;">当需要根据流水号查询数据时使用</td> </tr> <tr style="border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;"><code>bill_date</code></td> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;">唯一联合索引</td> <td style="border-color: rgb(204, 204, 204);color: rgb(100, 86, 71);min-width: 85px;">当需要根据日期查询数据时使用</td> </tr> </tbody> </table> </section> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">到这里就有了最基本的建表语句,主要是用来创建第一张月份账单表,如果想要实现动态按照每月建表的话,还需要用到存储过程来实现,接着来写一个存储过程。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 1.75;margin-top: 0.8em;margin-bottom: 0.8em;">最终撰写出的存储过程如下:</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="display: block;background: url(&quot;https://mmbiz.qpic.cn/mmbiz_svg/A7sq8BD8oezBibiciavS1eDQVpKdKQvg6wWj5ASkJmxWV4umyR2wB45aPZpW6R8zcJiaUXoFmIxXGVuXjnKyKk2bmV244xlc0mtq/640?wx_fmt=svg&quot;) 10px 10px / 40px no-repeat rgb(255, 255, 255);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: black;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #fff;border-radius: 5px;">DELIMITER&nbsp;//&nbsp;<br><span style="color: #aa0d91;line-height: 26px;">DROP</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">PROCEDURE</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">IF</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">EXISTS</span>&nbsp;create_table_by_month&nbsp;//<br><span style="color: #aa0d91;line-height: 26px;">CREATE</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">PROCEDURE</span>&nbsp;<span style="color: #c41a16;line-height: 26px;">`create_table_by_month`</span>()<br><span style="color: #aa0d91;line-height: 26px;">BEGIN</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #007400;line-height: 26px;">--&nbsp;用于记录下一个月份是多久</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #aa0d91;line-height: 26px;">DECLARE</span>&nbsp;nextMonth&nbsp;<span style="color: #5c2699;line-height: 26px;">varchar</span>(<span style="color: #1c00cf;line-height: 26px;">20</span>);<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #007400;line-height: 26px;">--&nbsp;用于记录创建表的SQL语句</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #aa0d91;line-height: 26px;">DECLARE</span>&nbsp;createTableSQL&nbsp;<span style="color: #5c2699;line-height: 26px;">varchar</span>(<span style="color: #1c00cf;line-height: 26px;">5210</span>);<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #007400;line-height: 26px;">--&nbsp;执行创建表的SQL语句后,获取表的数量</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #aa0d91;line-height: 26px;">DECLARE</span>&nbsp;tableCount&nbsp;<span style="color: #5c2699;line-height: 26px;">int</span>;<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #007400;line-height: 26px;">--&nbsp;用于记录要生成的表名</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #aa0d91;line-height: 26px;">DECLARE</span>&nbsp;tableName&nbsp;<span style="color: #5c2699;line-height: 26px;">varchar</span>(<span style="color: #1c00cf;line-height: 26px;">20</span>);<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #007400;line-height: 26px;">--&nbsp;用于记录表的前缀</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #aa0d91;line-height: 26px;">DECLARE</span>&nbsp;table_prefix&nbsp;<span style="color: #5c2699;line-height: 26px;">varchar</span>(<span style="color: #1c00cf;line-height: 26px;">20</span>);<br><br>&nbsp;&nbsp;<span style="color: #007400;line-height: 26px;">--&nbsp;获取下个月的日期并赋值给nextMonth变量</span><br>&nbsp;&nbsp;<span style="color: #aa0d91;line-height: 26px;">SELECT</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">SUBSTR</span>(<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #aa0d91;line-height: 26px;">replace</span>(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #aa0d91;line-height: 26px;">DATE_ADD</span>(<span style="color: #aa0d91;line-height: 26px;">CURDATE</span>(),&nbsp;<span style="color: #5c2699;line-height: 26px;">INTERVAL</span>&nbsp;<span style="color: #1c00cf;line-height: 26px;">1</span>&nbsp;<span style="color: #aa0d91;line-height: 26px;">MONTH</span>),<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #c41a16;line-height: 26px;">'-'</span>,&nbsp;<span style="color: #c41a16;line-height: 26px;">''</span>),<br>&nbsp;&nbsp;<span style="color: #1c00cf;line-height: 26px;">1</span>,&nbsp;<span style="color: #1c00cf;line-height: 26px;">6</span>)&nbsp;<span style="color: #aa0d91;line-height: 26px;">INTO</span>&nbsp;@nextMonth;<br><br>&nbsp;&nbsp;<span style="color: #007400;line-height: 26px;">--&nbsp;设置表前缀变量值为td_user_banks_log_</span><br>&nbsp;&nbsp;<span style="color: #aa0d91;line-height: 26px;">set</span>&nbsp;@table_prefix&nbsp;=&nbsp;<span style="color: #c41a16;line-height: 26px;">'month_bills_'</span>;<br><br>&nbsp;&nbsp;<span style="color: #007400;line-height: 26px;">--&nbsp;定义表的名称=表前缀+月份,即&nbsp;month_bills_2022112&nbsp;这个格式</span><br>&nbsp;&nbsp;<span style="color: #aa0d91;line-height: 26px;">SET</span>&nbsp;@tableName&nbsp;=&nbsp;<span style="color: #aa0d91;line-height: 26px;">CONCAT</span>(@table_prefix,&nbsp;@nextMonth);<br>&nbsp;&nbsp;<span style="color: #007400;line-height: 26px;">--&nbsp;定义创建表的SQL语句</span><br>&nbsp;&nbsp;<span style="color: #aa0d91;line-height: 26px;">set</span>&nbsp;@createTableSQL=<span style="color: #aa0d91;line-height: 26px;">concat</span>(<span style="color: #c41a16;line-height: 26px;">"create&nbsp;table&nbsp;if&nbsp;not&nbsp;exists&nbsp;"</span>,@tableName,<span style="color: #c41a16;line-height: 26px;">"(<br>&nbsp;&nbsp;&nbsp;&nbsp;`month_bills_id`&nbsp;int(8)&nbsp;NOT&nbsp;NULL&nbsp;AUTO_INCREMENT&nbsp;COMMENT&nbsp;'账单ID',<br>&nbsp;&nbsp;&nbsp;&nbsp;`serial_number`&nbsp;varchar(50)&nbsp;NOT&nbsp;NULL&nbsp;COMMENT&nbsp;'流水号',<br>&nbsp;&nbsp;&nbsp;&nbsp;`bills_info`&nbsp;text&nbsp;NOT&nbsp;NULL&nbsp;COMMENT&nbsp;'账单详情',<br>&nbsp;&nbsp;&nbsp;&nbsp;`pay_money`&nbsp;decimal(10,3)&nbsp;NOT&nbsp;NULL&nbsp;COMM

Spring Boot + Disruptor = 王炸!

作者:微信小助手

<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" data-mpa-powered-by="yiban.io" style="margin: 0px 0px 24px;padding: 0px 10px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;orphans: 2;text-indent: 0px;text-transform: none;white-space: normal;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration-style: initial;text-decoration-color: initial;color: black;word-break: break-word;text-align: left;font-size: 16px;letter-spacing: 2px;line-height: 1.75em;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;visibility: visible;"> <p style="text-align: center;"><img class="rich_pages wxw-img" data-ratio="0.23427672955974843" data-s="300,640" src="/upload/2bbe3027dbbac55fe259ab69f077bced.null" data-type="gifwxfrom=5wx_lazy=1" data-w="636" style=""></p> <section> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-weui-theme="light" data-id="Mzg2OTA0Njk0OA==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/iaIdQfEric9TxKIURWHe026Z5o2hVTdrjIu0h3VUG6c8CotnlvSdgzNMyfBajdrDgrPbx9uic84fH7ogllkicicZpXg/0?wx_fmt=png" data-nickname="JavaGuide" data-alias="JavaGuide" data-signature="专注 Java 原创面试干货分享!" data-from="0" data-is_biz_ban="0"></mp-common-profile> </section> <h2 data-tool="mdnice编辑器" style="margin: 0.8em auto;padding: 0.5em 0px;outline: 0px;font-weight: bold;font-size: 21px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;min-height: 32px;line-height: 28px;color: rgb(41, 128, 185);border-bottom: 1px solid rgb(52, 152, 219);border-top-color: rgb(52, 152, 219);border-right-color: rgb(52, 152, 219);border-left-color: rgb(52, 152, 219);text-align: center;width: 558.45px;display: flex;flex-direction: column;justify-content: center;visibility: visible;">Disruptor 介绍</h2> <p data-tool="mdnice编辑器" style="margin: 1em 2px;padding: 8px 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;clear: both;min-height: 1em;line-height: 26px;visibility: visible;"><code style="margin: 0px 2px;padding: 2px 4px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-size: 14px;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(41, 128, 185);visibility: visible;">Disruptor</code>&nbsp;是一个开源的高性能内存队列,由英国外汇交易公司 LMAX 开发的,获得了 2011 年的 Oracle 官方的 Duke's Choice Awards(Duke 选择大奖)。</p> <figure data-tool="mdnice编辑器" style="margin: 10px 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;display: flex;flex-direction: column;justify-content: center;align-items: center;visibility: visible;"> <img class="rich_pages wxw-img" data-ratio="0.7157407407407408" src="/upload/1dfef631f47bf42ae35f23a0d93f7194.png" data-type="png" data-w="1080" style="margin: 0px auto;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;vertical-align: bottom;height: auto !important;display: block;visibility: visible !important;width: 677px !important;"> </figure> <blockquote data-tool="mdnice编辑器" style="margin: 20px 5px;padding: 10px 10px 10px 20px;outline: 0px;border-left: 2.3px solid rgb(52, 152, 219);color: rgb(97, 97, 97);font-size: 0.9em;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;border-top: none;border-right: none;border-bottom: none;quotes: none;overflow: auto;background: rgb(236, 240, 241);visibility: visible;"> <p style="margin: 0px;padding: 8px 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;clear: both;min-height: 1em;font-size: 15px;color: black;line-height: 26px;visibility: visible;">“Duke 选择大奖”旨在表彰过去一年里全球个人或公司开发的、最具影响力的 Java 技术应用,由甲骨文公司主办。含金量非常高!</p> </blockquote> <p data-tool="mdnice编辑器" style="margin: 1em 2px;padding: 8px 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;clear: both;min-height: 1em;line-height: 26px;">我专门找到了 Oracle 官方当年颁布获得 Duke's Choice Awards 项目的那篇文章(文章地址:<strong style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(52, 152, 219);">https://blogs.oracle.com/java/post/and-the-winners-arethe-dukes-choice-award</strong>) 。从文中可以看出,同年获得此大奖荣誉的还有大名鼎鼎的 Netty 、JRebel 等项目。</p> <figure data-tool="mdnice编辑器" style="margin: 10px 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img js_img_placeholder" data-ratio="1.267429760665973" src="/upload/310b49c305b51a04bdc6948a9bd9d800.png" data-type="png" data-w="961" style="margin: 0px auto;padding: 0px;outline: 0px;background-size: 16px;border-radius: 8px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;vertical-align: bottom;height: 858.05px !important;display: block;width: 677px !important;"> <figcaption style="margin: 5px 0px 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;text-align: center;color: rgb(136, 136, 136);font-size: 14px;"> 2011 年的 Oracle 官方的 Duke's Choice Awards </figcaption> </figure> <p data-tool="mdnice编辑器" style="margin: 1em 2px;padding: 8px 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;clear: both;min-height: 1em;line-height: 26px;">并且,有一些知名的开源项目到了&nbsp;<code style="margin: 0px 2px;padding: 2px 4px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-size: 14px;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(41, 128, 185);">Disruptor</code>&nbsp;,就比如性能强大的 Java 日志框架&nbsp;<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-weight: bold;color: rgb(44, 62, 80);">Log4j 2</span><sup style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;line-height: 0;font-weight: bold;color: rgb(44, 62, 80);">[1]</sup>&nbsp;和蚂蚁金服分布式链路跟踪组件&nbsp;<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-weight: bold;color: rgb(44, 62, 80);">SOFATracer</span><sup style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;line-height: 0;font-weight: bold;color: rgb(44, 62, 80);">[2]</sup>&nbsp;就是基于 Disruptor 来做的异步日志,相关阅读:<span style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-weight: bold;color: rgb(44, 62, 80);">蚂蚁金服分布式链路跟踪组件 SOFATracer 中 Disruptor 实践(含源码)</span><sup style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;line-height: 0;font-weight: bold;color: rgb(44, 62, 80);">[3]</sup>。</p> <figure data-tool="mdnice编辑器" style="margin: 10px 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img js_img_placeholder" data-ratio="0.488" src="/upload/7548fe5244ac1fb89b4bf48a3b085f22.png" data-type="png" data-w="2000" style="margin: 0px auto;padding: 0px;outline: 0px;background-size: 16px;border-radius: 8px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;vertical-align: bottom;height: 330.376px !important;display: block;width: 677px !important;"> </figure> <p data-tool="mdnice编辑器" style="margin: 1em 2px;padding: 8px 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;clear: both;min-height: 1em;line-height: 26px;"><code style="margin: 0px 2px;padding: 2px 4px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-size: 14px;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(41, 128, 185);">Disruptor</code>&nbsp;提供的功能类似于&nbsp;<code style="margin: 0px 2px;padding: 2px 4px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-size: 14px;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(41, 128, 185);">Kafka</code>、<code style="margin: 0px 2px;padding: 2px 4px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-size: 14px;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(41, 128, 185);">RocketMQ</code>&nbsp;这类分布式队列,不过,其作为范围是 JVM(内存)。</p> <ul data-tool="mdnice编辑器" class="list-paddingleft-1" style="margin: 8px 0px;padding: 0px 0px 0px 25px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-size: 15px;"> <li style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section style="margin: 10px 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;line-height: 26px;color: rgb(1, 1, 1);"> Github 地址: <strong style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(52, 152, 219);">https://github.com/LMAX-Exchange/disruptor</strong> </section></li> <li style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section style="margin: 10px 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;line-height: 26px;color: rgb(1, 1, 1);"> 官方教程: <strong style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;color: rgb(52, 152, 219);">https://lmax-exchange.github.io/disruptor/user-guide/index.html</strong> </section></li> </ul> <p data-tool="mdnice编辑器" style="margin: 1em 2px;padding: 8px 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;clear: both;min-height: 1em;line-height: 26px;"><code style="margin: 0px 2px;padding: 2px 4px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-size: 14px;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(41, 128, 185);">Disruptor</code>&nbsp;解决了 JDK 内置线程安全队列的性能和内存安全问题。</p> <p data-tool="mdnice编辑器" style="margin: 1em 2px;padding: 8px 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;clear: both;min-height: 1em;line-height: 26px;">JDK 中常见的线程安全的队列如下:</p> <section data-tool="mdnice编辑器" style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;overflow-x: auto;"> <table width="656"> <thead style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <tr style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <th style="margin: 0px;padding: 5px 10px;outline: 0px;overflow-wrap: break-word !important;word-break: break-all;border-color: rgb(204, 204, 204);border-style: solid;border-width: 1px;background: rgb(240, 240, 240);max-width: 100%;box-sizing: border-box !important;text-align: left;font-size: 15px;min-width: 85px;">队列名字</th> <th style="margin: 0px;padding: 5px 10px;outline: 0px;overflow-wrap: break-word !important;word-break: break-all;border-color: rgb(204, 204, 204);border-style: solid;border-width: 1px;background: rgb(240, 240, 240);max-width: 100%;box-sizing: border-box !important;text-align: left;font-size: 15px;min-width: 85px;">锁</th> <th style="margin: 0px;padding: 5px 10px;outline: 0px;overflow-wrap: break-word !important;word-break: break-all;border-color: rgb(204, 204, 204);border-style: solid;border-width: 1px;background: rgb(240, 240, 240);max-width: 100%;box-sizing: border-box !important;text-align: left;font-size: 15px;min-width: 85px;">是否有界</th> </tr> </thead> <tbody style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;border-width: 0px;border-style: initial;border-color: initial;"> <tr style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td style="margin: 0px;padding: 5px 10px;outline: 0px;overflow-wrap: break-word !important;word-break: break-all;border-color: rgb(204, 204, 204);border-style: solid;border-width: 1px;max-width: 100%;box-sizing: border-box !important;font-size: 15px;min-width: 85px;"><code style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">ArrayBlockingQueue</code></td> <td style="margin: 0px;padding: 5px 10px;outline: 0px;overflow-wrap: break-word !important;word-break: break-all;border-color: rgb(204, 204, 204);border-style: solid;border-width: 1px;max-width: 100%;box-sizing: border-box !important;font-size: 15px;min-width: 85px;">加锁(<code style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">ReentrantLock</code>)</td> <td style="margin: 0px;padding: 5px 10px;outline: 0px;overflow-wrap: break-word !important;word-break: break-all;border-color: rgb(204, 204, 204);border-style: solid;border-width: 1px;max-width: 100%;box-sizing: border-box !important;font-size: 15px;min-width: 85px;">有界</td> </tr> <tr style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: rgb(248, 248, 248);"> <td style="margin: 0px;padding: 5px 10px;outline: 0px;overflow-wrap: break-word !important;word-break: break-all;border-color: rgb(204, 204, 204);border-style: solid;border-width: 1px;max-width: 100%;box-sizing: border-box !important;font-size: 15px;min-width: 85px;"><code style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">LinkedBlockingQueue</code></td> <td style="margin: 0px;padding: 5px 10px;outline: 0px;overflow-wrap: break-word !important;word-break: break-all;border-color: rgb(204, 204, 204);border-style: solid;border-width: 1px;max-width: 100%;box-sizing: border-box !important;font-size: 15px;min-width: 85px;">加锁(<code style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">ReentrantLock</code>)</td> <td style="margin: 0px;padding: 5px 10px;outline: 0px;overflow-wrap: break-word !important;word-break: break-all;border-color: rgb(204, 204, 204);border-style: solid;border-width: 1px;max-width: 100%;box-sizing: border-box !important;font-size: 15px;min-width: 85px;">有界</td> </tr> <tr style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td style="margin: 0px;padding: 5px 10px;outline: 0px;overflow-wrap: break-word !important;word-break: break-all;border-color: rgb(204, 204, 204);border-style: solid;border-width: 1px;max-width: 100%;box-sizing: border-box !important;font-size: 15px;min-width: 85px;"><code style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">LinkedTransferQueue</code></td> <td style="margin: 0px;padding: 5px 10px;outline: 0px;overflow-wrap: break-word !important;word-break: break-all;border-color: rgb(204, 204, 204);border-style: solid;border-width: 1px;max-width: 100%;box-sizing: border-box !important;font-size: 15px;min-width: 85px;">无锁(<code style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">CAS</code>)</td> <td style="margin: 0px;padding: 5px 10px;outline: 0px;overflow-wrap: break-word !important;word-break: break-all;border-color: rgb(204, 204, 204);border-style: solid;border-width: 1px;max-width: 100%;box-sizing: border-box !important;font-size: 15px;min-width: 85px;">无界</td> </tr> <tr style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: rgb(248, 248, 248);"> <td style="margin: 0px;padding: 5px 10px;outline: 0px;overflow-wrap: break-word !important;word-break: break-all;border-color: rgb(204, 204, 204);border-style: solid;border-width: 1px;max-width: 100%;box-sizing: border-box !important;font-size: 15px;min-width: 85px;"><code style="margin: 0px;padding: 0px;outline: 0px;max-width: 100%;box

优秀运维脚本鉴赏

作者:微信小助手

<section data-mpa-powered-by="yiban.io"> <section> <section> <section data-tool="编辑器" data-website="https://jsjson.com"> <section> <section style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;"> <p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">一、根据PID过滤进程所有信息</p> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);background: rgb(40, 43, 46);padding: 0.5em;overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(91, 218, 237);overflow-wrap: inherit !important;word-break: inherit !important;">#!&nbsp;/bin/bash</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(128, 128, 128);overflow-wrap: inherit !important;word-break: inherit !important;">#&nbsp;Function:&nbsp;根据用户输入的PID,过滤出该PID所有的信息</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">read</span>&nbsp;-p&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"请输入要查询的PID:&nbsp;"</span>&nbsp;P<br>n=`ps&nbsp;-aux|&nbsp;awk&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'$2~/^'</span><span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$P</span><span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'$/{print&nbsp;$11}'</span>|wc&nbsp;-l`<br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">if</span>&nbsp;[&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$n</span>&nbsp;-eq&nbsp;0&nbsp;];<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">then</span><br>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"该PID不存在!!"</span><br>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">exit</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">fi</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"--------------------------------"</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"进程PID:&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$P</span>"</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"进程命令:`ps -aux| awk '<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$2</span>~/^'<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$P</span>'$/{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$11</span>}'`"</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"进程所属用户:&nbsp;`ps&nbsp;-aux|&nbsp;awk&nbsp;'<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$2</span>~/^'<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$P</span>'$/{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$1</span>}'`"</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"CPU占用率:`ps -aux| awk '<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$2</span>~/^'<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$P</span>'$/{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$3</span>}'`%"</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"内存占用率:`ps -aux| awk '<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$2</span>~/^'<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$P</span>'$/{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$4</span>}'`%"</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"进程开始运行的时刻:`ps -aux| awk '<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$2</span>~/^'<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$P</span>'$/{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$9</span>}'`"</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"进程运行的时间:`ps -aux| awk '<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$2</span>~/^'<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$P</span>'$/{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$10</span>}'`"</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"进程状态:`ps -aux| awk '<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$2</span>~/^'<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$P</span>'$/{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$8</span>}'`"</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"进程虚拟内存:`ps -aux| awk '<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$2</span>~/^'<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$P</span>'$/{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$5</span>}'`"</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"进程共享内存:`ps -aux| awk '<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$2</span>~/^'<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$P</span>'$/{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$6</span>}'`"</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"--------------------------------"</span><br></code></pre> <p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;"><img class="rich_pages wxw-img" src="/upload/2802817b43f5c945dce0911b6f5f160d.png" data-type="png" data-ratio="0.7664359861591695" data-w=""></p> <p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">二、根据进程名过滤进程信息<br>会显示出该进程名包含的所有线程</p> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);background: rgb(40, 43, 46);padding: 0.5em;overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(91, 218, 237);overflow-wrap: inherit !important;word-break: inherit !important;">#!&nbsp;/bin/bash</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(128, 128, 128);overflow-wrap: inherit !important;word-break: inherit !important;">#&nbsp;Function:&nbsp;根据输入的程序的名字过滤出所对应的PID,并显示出详细信息,如果有几个PID,则全部显示</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">read</span>&nbsp;-p&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"请输入要查询的进程名:"</span>&nbsp;NAME<br>N=`ps&nbsp;-aux&nbsp;|&nbsp;grep&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$NAME</span>&nbsp;|&nbsp;grep&nbsp;-v&nbsp;grep&nbsp;|&nbsp;wc&nbsp;-l`&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(128, 128, 128);overflow-wrap: inherit !important;word-break: inherit !important;">##统计进程总数</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">if</span>&nbsp;[&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$N</span>&nbsp;-le&nbsp;0&nbsp;];<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">then</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"该进程名没有运行!"</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">fi</span><br>i=1<br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">while</span>&nbsp;[&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$N</span>&nbsp;-gt&nbsp;0&nbsp;]<br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">do</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"进程PID:&nbsp;`ps&nbsp;-aux&nbsp;|&nbsp;grep&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$NAME</span>&nbsp;|&nbsp;grep&nbsp;-v&nbsp;grep&nbsp;|&nbsp;awk&nbsp;'NR=='<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$i</span>'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$0</span>}'|&nbsp;awk&nbsp;'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$2</span>}'`"</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"进程命令:`ps -aux | grep <span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$NAME</span>&nbsp;|&nbsp;grep&nbsp;-v&nbsp;grep&nbsp;|&nbsp;awk&nbsp;'NR=='<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$i</span>'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$0</span>}'|&nbsp;awk&nbsp;'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$11</span>}'`"</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"进程所属用户:&nbsp;`ps&nbsp;-aux&nbsp;|&nbsp;grep&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$NAME</span>&nbsp;|&nbsp;grep&nbsp;-v&nbsp;grep&nbsp;|&nbsp;awk&nbsp;'NR=='<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$i</span>'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$0</span>}'|&nbsp;awk&nbsp;'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$1</span>}'`"</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"CPU占用率:`ps -aux | grep <span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$NAME</span>&nbsp;|&nbsp;grep&nbsp;-v&nbsp;grep&nbsp;|&nbsp;awk&nbsp;'NR=='<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$i</span>'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$0</span>}'|&nbsp;awk&nbsp;'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$3</span>}'`%"</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"内存占用率:`ps -aux | grep <span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$NAME</span>&nbsp;|&nbsp;grep&nbsp;-v&nbsp;grep&nbsp;|&nbsp;awk&nbsp;'NR=='<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$i</span>'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$0</span>}'|&nbsp;awk&nbsp;'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$4</span>}'`%"</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"进程开始运行的时刻:`ps -aux | grep <span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$NAME</span>&nbsp;|&nbsp;grep&nbsp;-v&nbsp;grep&nbsp;|&nbsp;awk&nbsp;'NR=='<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$i</span>'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$0</span>}'|&nbsp;awk&nbsp;'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$9</span>}'`"</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"进程运行的时间:` ps -aux | grep <span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$NAME</span>&nbsp;|&nbsp;grep&nbsp;-v&nbsp;grep&nbsp;|&nbsp;awk&nbsp;'NR=='<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$i</span>'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$0</span>}'|&nbsp;awk&nbsp;'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$11</span>}'`"</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"进程状态:`ps -aux | grep <span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$NAME</span>&nbsp;|&nbsp;grep&nbsp;-v&nbsp;grep&nbsp;|&nbsp;awk&nbsp;'NR=='<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$i</span>'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$0</span>}'|&nbsp;awk&nbsp;'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$8</span>}'`"</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"进程虚拟内存:`ps -aux | grep <span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$NAME</span>&nbsp;|&nbsp;grep&nbsp;-v&nbsp;grep&nbsp;|&nbsp;awk&nbsp;'NR=='<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$i</span>'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$0</span>}'|&nbsp;awk&nbsp;'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$5</span>}'`"</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"进程共享内存:`ps -aux | grep <span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$NAME</span>&nbsp;|&nbsp;grep&nbsp;-v&nbsp;grep&nbsp;|&nbsp;awk&nbsp;'NR=='<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$i</span>'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$0</span>}'|&nbsp;awk&nbsp;'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$6</span>}'`"</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"***************************************************************"</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">let</span>&nbsp;N--&nbsp;i++<br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">done</span><br></code></pre> <p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;"><img class="rich_pages wxw-img" data-ratio="0.7121354656632173" src="/upload/1449301ad6cf8192673805485fcb52a.png" data-type="png" data-w="1063"></p> <p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">三、根据用户名查询该用户的相关信息</p> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);background: rgb(40, 43, 46);padding: 0.5em;overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(91, 218, 237);overflow-wrap: inherit !important;word-break: inherit !important;">#!&nbsp;/bin/bash</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(128, 128, 128);overflow-wrap: inherit !important;word-break: inherit !important;"># Function:根据用户名查询该用户的所有信息</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">read</span>&nbsp;-p&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"请输入要查询的用户名:"</span>&nbsp;A<br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"------------------------------"</span><br>n=`cat&nbsp;/etc/passwd&nbsp;|&nbsp;awk&nbsp;-F:&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'$1~/^'</span><span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$A</span><span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'$/{print}'</span>&nbsp;|&nbsp;wc&nbsp;-l`<br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">if</span>&nbsp;[&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$n</span>&nbsp;-eq&nbsp;0&nbsp;];<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">then</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"该用户不存在"</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"------------------------------"</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">else</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"该用户的用户名:<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$A</span>"</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"该用户的UID:`cat /etc/passwd | awk -F:&nbsp;'<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$1</span>~/^'<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$A</span>'$/{print}'|awk&nbsp;-F:&nbsp;'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$3</span>}'`"</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"该用户的组为:`id <span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$A</span>&nbsp;|&nbsp;awk&nbsp;{'print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$3</span>'}`"</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"该用户的GID为:`cat /etc/passwd | awk -F:&nbsp;'<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$1</span>~/^'<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$A</span>'$/{print}'|awk&nbsp;-F:&nbsp;'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$4</span>}'`"</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"该用户的家目录为:`cat /etc/passwd | awk -F:&nbsp;'<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$1</span>~/^'<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$A</span>'$/{print}'|awk&nbsp;-F:&nbsp;'{print&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$6</span>}'`"</span><br>&nbsp;&nbsp;Login=`cat&nbsp;/etc/passwd&nbsp;|&nbsp;awk&nbsp;-F:&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'$1~/^'</span><span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$A</span><span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'$/{print}'</span>|awk&nbsp;-F:&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'{print&nbsp;$7}'</span>`<br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">if</span>&nbsp;[&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$Login</span>&nbsp;==&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"/bin/bash"</span>&nbsp;];<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">then</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"该用户有登录系统的权限!!"</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"------------------------------"</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">elif</span>&nbsp;[&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$Login</span>&nbsp;==&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"/sbin/nologin"</span>&nbsp;];<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">then</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"该用户没有登录系统的权限!!"</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"------------------------------"</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">fi</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">fi</span><br></code></pre> <p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;"><img class="rich_pages wxw-img" data-ratio="0.4763358778625954" src="/upload/537a35868fb56b96efda44e3369150de.png" data-type="png" data-w="655"></p> <p style="font-size: inherit;color: inherit;line-height: inherit;margin-top: 1.5em;margin-bottom: 1.5em;">四、加固系统的一些配置</p> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);background: rgb(40, 43, 46);padding: 0.5em;overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(91, 218, 237);overflow-wrap: inherit !important;word-break: inherit !important;">#!&nbsp;/bin/bash</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(128, 128, 128);overflow-wrap: inherit !important;word-break: inherit !important;">#&nbsp;Function:对账户的密码的一些加固</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">read</span>&nbsp;-p&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"设置密码最多可多少天不修改:"</span>&nbsp;A<br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">read</span>&nbsp;-p&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"设置密码修改之间最小的天数:"</span>&nbsp;B<br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">read</span>&nbsp;-p&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"设置密码最短的长度:"</span>&nbsp;C<br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">read</span>&nbsp;-p&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"设置密码失效前多少天通知用户:"</span>&nbsp;D<br>sed&nbsp;-i&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'/^PASS_MAX_DAYS/c\PASS_MAX_DAYS&nbsp;'</span><span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$A</span><span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">''</span>&nbsp;/etc/login.defs<br>sed&nbsp;-i&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'/^PASS_MIN_DAYS/c\PASS_MIN_DAYS&nbsp;'</span><span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$B</span><span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">''</span>&nbsp;/etc/login.defs<br>sed&nbsp;-i&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'/^PASS_MIN_LEN/c\PASS_MIN_LEN&nbsp;'</span><span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$C</span><span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">''</span>&nbsp;/etc/login.defs<br>sed&nbsp;-i&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'/^PASS_WARN_AGE/c\PASS_WARN_AGE&nbsp;'</span><span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$D</span><span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">''</span>&nbsp;/etc/login.defs<br><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"已对密码进行加固,新用户不得和旧密码相同,且新密码必须同时包含数字、小写字母,大写字母!!"</span><br>sed&nbsp;-i&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'/pam_pwquality.so/c\password&nbsp;requisite&nbsp;pam_pwquality.so&nbsp;try_first_pass&nbsp;local_users_only&nbsp;retry=3&nbsp;authtok_type=&nbsp;difok=1&nbsp;minlen=8&nbsp;ucredit=-1&nbsp;lcredit=-1&nbsp;dcredit=-1'</span>&nbsp;/etc/pam.d/system-auth<br><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"已对密码进行加固,如果输入错误密码超过3次,则锁定账户!!"</span><br>n=`cat&nbsp;/etc/pam.d/sshd&nbsp;|&nbsp;grep&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"auth&nbsp;required&nbsp;pam_tally2.so&nbsp;"</span>|wc&nbsp;-l`<br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">if</span>&nbsp;[&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$n</span>&nbsp;-eq&nbsp;0&nbsp;];<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">then</span><br>sed&nbsp;-i&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'/%PAM-1.0/a\auth&nbsp;required&nbsp;pam_tally2.so&nbsp;deny=3&nbsp;unlock_time=150&nbsp;even_deny_root&nbsp;root_unlock_time300'</span>&nbsp;/etc/pam.d/sshd<br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">fi</span><br><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"已设置禁止root用户远程登录!!"</span><br>sed&nbsp;-i&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'/PermitRootLogin/c\PermitRootLogin&nbsp;no'</span>&nbsp;&nbsp;/etc/ssh/sshd_config<br><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">read</span>&nbsp;-p&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"设置历史命令保存条数:"</span>&nbsp;E<br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">read</span>&nbsp;-p&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"设置账户自动注销时间:"</span>&nbsp;F<br>sed&nbsp;-i&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'/^HISTSIZE/c\HISTSIZE='</span><span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$E</span><span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">''</span>&nbsp;/etc/profile<br>sed&nbsp;-i&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'/^HISTSIZE/a\TMOUT='</span><span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$F</span><span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">''</span>&nbsp;/etc/profile<br><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"已设置只允许wheel组的用户可以使用su命令切换到root用户!"</span><br>sed&nbsp;-i&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'/pam_wheel.so&nbsp;use_uid/c\auth&nbsp;required&nbsp;pam_wheel.so&nbsp;use_uid&nbsp;'</span>&nbsp;/etc/pam.d/su<br>n=`cat&nbsp;/etc/login.defs&nbsp;|&nbsp;grep&nbsp;SU_WHEEL_ONLY&nbsp;|&nbsp;wc&nbsp;-l`<br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">if</span>&nbsp;[&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$n</span>&nbsp;-eq&nbsp;0&nbsp;];<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">then</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;SU_WHEEL_ONLY&nbsp;yes&nbsp;&gt;&gt;&nbsp;/etc/login.defs<br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">fi</span><br><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"即将对系统中的账户进行检查...."</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"系统中有登录权限的用户有:"</span><br>awk&nbsp;-F:&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'($7=="/bin/bash"){print&nbsp;$1}'</span>&nbsp;/etc/passwd<br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"********************************************"</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"系统中UID=0的用户有:"</span><br>awk&nbsp;-F:&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'($3=="0"){print&nbsp;$1}'</span>&nbsp;/etc/passwd<br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"********************************************"</span><br>N=`awk&nbsp;-F:&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'($2==""){print&nbsp;$1}'</span>&nbsp;/etc/shadow|wc&nbsp;-l`<br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"系统中空密码用户有:<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$N</span>"</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">if</span>&nbsp;[&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$N</span>&nbsp;-eq&nbsp;0&nbsp;];<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">then</span><br>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"恭喜你,系统中无空密码用户!!"</span><br>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"********************************************"</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">else</span><br>&nbsp;i=1<br>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">while</span>&nbsp;[&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$N</span>&nbsp;-gt&nbsp;0&nbsp;]<br>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">do</span><br>&nbsp;&nbsp;&nbsp;&nbsp;None=`awk&nbsp;-F:&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'($2==""){print&nbsp;$1}'</span>&nbsp;/etc/shadow|awk&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'NR=='</span><span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$i</span><span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'{print}'</span>`<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"------------------------"</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$None</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"必须为空用户设置密码!!"</span><br>&nbsp;&nbsp;&nbsp;&nbsp;passwd&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$None</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">let</span>&nbsp;N--<br>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">done</span><br>&nbsp;M=`awk&nbsp;-F:&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">'($2==""){print&nbsp;$1}'</span>&nbsp;/etc/shadow|wc&nbsp;-l`<br>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">if</span>&nbsp;[&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$M</span>&nbsp;-eq&nbsp;0&nbsp;];<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">then</span><br>&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"恭喜,系统中已经没有空密码用户了!"</span><br>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">else</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"系统中还存在空密码用户:<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$M</span>"</span><br>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">fi</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">fi</span><br><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"即将对系统中重要文件进行锁定,锁定后将无法添加删除用户和组"</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">read</span>&nbsp;-p&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"警告:此脚本运行后将无法添加删除用户和组!!确定输入Y,取消输入N;Y/N:"</span>&nbsp;i<br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">case</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(98, 151, 85);overflow-wrap: inherit !important;word-break: inherit !important;">$i</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">in</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Y,y])<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chattr&nbsp;+i&nbsp;/etc/passwd<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chattr&nbsp;+i&nbsp;/etc/shadow<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chattr&nbsp;+i&nbsp;/etc/group<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chattr&nbsp;+i&nbsp;/etc/gshadow<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"锁定成功!"</span><br>;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[N,n])<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chattr&nbsp;-i&nbsp;/etc/passwd<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chattr&nbsp;-i&nbsp;/etc/shadow<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chattr&nbsp;-i&nbsp;/etc/group<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chattr&nbsp;-i&nbsp;/etc/gshadow<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"取消锁定成功!!"</span><br>;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">echo</span>&nbsp;<span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);overflow-wrap: inherit !important;word-break: inherit !important;">"请输入Y/y&nbsp;or&nbsp;N/n"</span><br><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">esac</span><br></code></pre> </section> <p data-track="190"><span style="font-size: 12px;"></span></p> <p data-track="190"><span style="font-size: 12px;"><img class="rich_pages wxw-img" data-ratio="0.5583333333333333" src="/upload/c53c7593dd5b97ac9ca8ac544c4ccc1e.png" data-type="png" data-w="1080"></span></p> <p data-track="190"><span style="font-size: 12px;">原作者:「已注销」</span><span style="font-size: 12px;"></span></p> <p data-track="190"><span style="font-size: 12px;">源链接:</span></p> <p data-track="190"><span style="font-size: 12px;"><span style="caret-color: rgba(0, 0, 0, 0.5);color: rgba(0, 0, 0, 0.5);font-family: system-ui, -apple-system, 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: 10px;letter-spacing: 0.544px;text-size-adjust: auto;background-color: rgb(255, 255, 255);">https://blog.csdn.net/lyshark_lyshark/article/details/125853245</span></span></p> <p data-track="190"><span style="font-size: 12px;">编辑:IT运维技术圈</span></p> </section> </section> </section> </section> </section>

关于MySQLl数据存储,你了解多少?

作者:微信小助手

<p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.625" data-s="300,640" data-type="jpeg" data-w="1024" style="height: auto !important;" src="/upload/19b425c06e7abdab71c715693b868dfd.jpg"></p> <section style="font-size: 15px;box-sizing: border-box;"> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;box-sizing: border-box;" powered-by="xiumi.us"> <section style="padding: 3px;display: inline-block;border-bottom: 5px solid rgb(255, 129, 36);color: rgb(255, 129, 36);font-size: 16px;box-sizing: border-box;"> <p style="box-sizing: border-box;">前言</p> </section> </section> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">大家都知道 MySQL 的数据都是保存在磁盘的,那具体是保存在哪个文件呢?MySQL 存储的行为是由存储引擎实现的,MySQL 支持多种存储引擎,不同的存储引擎保存的文件自然也不同。InnoDB 是我们常用的存储引擎,也是 MySQL 默认的存储引擎。本文主要以 InnoDB 存储引擎展开讨论。</span> </section> <section style="font-size: 15px;box-sizing: border-box;"> <section style="margin-top: 10px;margin-bottom: 10px;text-align: center;box-sizing: border-box;" powered-by="xiumi.us"> <section style="padding: 3px;display: inline-block;border-bottom: 5px solid rgb(255, 129, 36);color: rgb(255, 129, 36);font-size: 16px;box-sizing: border-box;"> <p style="box-sizing: border-box;">InnoDB简介</p> </section> </section> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">InnoDB是一个将表中的数据存储到磁盘上的存储引擎。而真正处理数据的过程是发生在内存中的,所以需要把磁盘中的数据加载到内存中,如果是处理写入或修改请求的话,还需要把内存中的内容刷新到磁盘上。而我们知道读写磁盘的速度非常慢,和内存读写差了几个数量级。所以当我们想从表中获取某些记录时,InnoDB存储引擎需要一条一条的把记录从磁盘上读出来么?想要了解这个问题,我们首先需要了解InnoDB的存储结构是怎样的。</span> </section> <section style="line-height: 1.75em;text-align: center;"> <img class="rich_pages wxw-img" data-ratio="1.0412573673870333" data-type="png" data-w="1018" width="509" style="height: auto !important;" src="/upload/7d9862f1fc6de8a8f9844103d9ec9379.png"> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">InnoDB采取的方式是:将数据划分为若干个页,以页作为磁盘和内存之间交互的基本单位innodb_page_size选项指定了MySQL实例的所有InnoDB表空间的页面大小。这个值是在创建实例时设置的,之后保持不变。有效值为64KB,32KB,16KB(默认值 ),8kB和4kB。也就是在一般情况下,一次最少从磁盘中读取16KB的内容到内存中,一次最少把内存中的16KB内容刷新到磁盘中。</span> </section> <section style="font-size: 15px;box-sizing: border-box;"> <section style="text-align: left;justify-content: flex-start;margin: 10px 0%;display: flex;flex-flow: row nowrap;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: bottom;width: auto;align-self: flex-end;flex: 0 0 0%;height: auto;line-height: 0;box-sizing: border-box;"> <section style="text-align: right;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;width: 18px;height: 18px;vertical-align: top;overflow: hidden;background-color: rgb(255, 129, 36);box-sizing: border-box;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> <section style="display: inline-block;vertical-align: bottom;width: auto;min-width: 10%;max-width: 100%;flex: 0 0 auto;height: auto;align-self: flex-end;box-sizing: border-box;"> <section style="color: rgb(62, 62, 62);font-size: 14px;padding-right: 4px;padding-left: 4px;line-height: 1;text-align: justify;box-sizing: border-box;" powered-by="xiumi.us"> <p style="white-space: normal;box-sizing: border-box;"><strong style="box-sizing: border-box;"><span style="font-size: 15px;box-sizing: border-box;">InnoDB行格式</span></strong></p> </section> </section> <section style="display: inline-block;vertical-align: middle;width: auto;align-self: center;min-width: 10%;max-width: 100%;flex: 0 0 auto;height: auto;line-height: 0;box-sizing: border-box;"> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">我们平时是以记录为单位来向表中插入数据的,这些记录在磁盘上的存放方式也被称为行格式或者记录格式。一行记录可以以不同的格式存在InnoDB中,行格式分别是compact、redundant、dynamic和compressed行格式。可以在创建或修改的语句中指定行格式:</span> </section> <pre data-language="sql"> <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="sql"><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">CREATE</span> <span class="code-snippet__keyword">TABLE</span> 表名 (列的信息) ROW_FORMAT=行格式名称;</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">ALTER</span> <span class="code-snippet__keyword">TABLE</span> 表名 ROW_FORMAT=行格式名称;</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">show</span> <span class="code-snippet__keyword">table</span> <span class="code-snippet__keyword">status</span> <span class="code-snippet__keyword">like</span> <span class="code-snippet__string">'&lt;数据表名&gt;'</span>;</span></code></pre> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);"></span> </section></pre> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">mysql5.0之前默认的行格式是redundant,mysql5.0之后的默认行格式为compact , 5.7之后的默认行格式为dynamic</span> </section> <h4 style="line-height: 1.75em;"><span style="font-size: 15px;color: rgb(255, 104, 39);">compact格式</span></h4> <section style="line-height: 1.75em;text-align: center;"> <img class="rich_pages wxw-img" data-ratio="0.27844311377245506" data-type="png" data-w="2004" width="1002" style="height: auto !important;" src="/upload/716211f896de448104cd6c683f013fa8.png"> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">记录的额外信息</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">记录的额外信息:分别是变长字段长度列表、NULL值列表和记录头信息</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">1:变长字段长度列表</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">mysql中支持一些变长数据类型(比如VARCHAR(M)、TEXT等),它们存储数据占用的存储空间不是固定的,而是会随着存储内容的变化而变化。在Compact行格式中,把所有变长字段的真实数据占用的字节长度都存放在记录的开头部位,从而形成一个变长字段长度列表,各变长字段数据占用的字节数按照列的顺序逆序存放</span> </section> <ul class="list-paddingleft-1"> <li style="font-size: 15px;color: rgb(62, 62, 62);"><p style="line-height: 1.75em;margin-bottom: 8px;"><span style="font-size: 15px;color: rgb(62, 62, 62);">变长字段长度列表中只存储值为 非NULL 的列内容占用的长度,值为 NULL 的列的长度是不储存的 。</span></p></li> <li style="font-size: 15px;color: rgb(62, 62, 62);"><p style="line-height: 1.75em;margin-bottom: 24px;"><span style="font-size: 15px;color: rgb(62, 62, 62);">并不是所有记录都有这个 变长字段长度列表 部分,比方说表中所有的列都不是变长的数据类型的话,这一部分就不需要有</span></p></li> </ul> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">2:NULL值列表</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">NULL值列表:Compact格式会把所有可以为NULL的列统一管理起来,存在一个NULL值列表,如果表中没有允许为NULL的列,则NULL值列表也不复存在了。</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">为什么要有NULL值列表?</span> </section> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">表中的某些列可能存储NULL值,如果把这些NULL值都放到记录的真实数据中存储会很浪费空间,所以Compact行格式把这些值为NULL的列统一管理起来,存储到NULL值列表中,它的处理过程是这样的:</span> </section> <ul class="list-paddingleft-1"> <li style="font-size: 15px;color: rgb(62, 62, 62);"><p style="line-height: 1.75em;margin-bottom: 8px;"><span style="font-size: 15px;color: rgb(62, 62, 62);">首先统计表中允许存储NULL的列有哪些。</span></p></li> <li style="font-size: 15px;color: rgb(62, 62, 62);"><p style="line-height: 1.75em;margin-bottom: 8px;"><span style="font-size: 15px;color: rgb(62, 62, 62);">根据列的实际值,用0或者1填充NULL值列表,1代表该列的值为空,0代表该列的值不为空。</span></p></li> <li style="font-size: 15px;color: rgb(62, 62, 62);"><p style="line-height: 1.75em;margin-bottom: 24px;"><span style="font-size: 15px;color: rgb(62, 62, 62);">如果表中没有允许存储 NULL 的列,则 NULL值列表 也不存在了。</span></p></li> </ul> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">3:记录头信息</span> </section> <table width="689"> <tbody> <tr style="height: 33px;"> <td width="176" style="border-color: rgb(217, 217, 217);background-color: rgb(217, 234, 252);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">名称</span> </section></td> <td width="181" style="border-color: rgb(217, 217, 217);background-color: rgb(217, 234, 252);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">大小(单位:bit)</span> </section></td> <td width="332" style="border-color: rgb(217, 217, 217);background-color: rgb(217, 234, 252);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">描述</span> </section></td> </tr> <tr style="height: 33px;"> <td width="176" style="border-color: rgb(217, 217, 217);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">预留位1</span> </section></td> <td width="181" style="border-color: rgb(217, 217, 217);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">1</span> </section></td> <td width="332" style="border-color: rgb(217, 217, 217);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">未使用</span> </section></td> </tr> <tr style="height: 33px;"> <td width="176" style="border-color: rgb(217, 217, 217);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">预留位2</span> </section></td> <td width="181" style="border-color: rgb(217, 217, 217);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">1</span> </section></td> <td width="332" style="border-color: rgb(217, 217, 217);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">未使用</span> </section></td> </tr> <tr style="height: 33px;"> <td width="176" style="border-color: rgb(217, 217, 217);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">delete_mask</span> </section></td> <td width="181" style="border-color: rgb(217, 217, 217);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">1</span> </section></td> <td width="332" style="border-color: rgb(217, 217, 217);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">标记改记录是否被删除</span> </section></td> </tr> <tr style="height: 33px;"> <td width="176" style="border-color: rgb(217, 217, 217);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">min_rec_mask</span> </section></td> <td width="181" style="border-color: rgb(217, 217, 217);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">1</span> </section></td> <td width="332" style="border-color: rgb(217, 217, 217);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">B+树非叶子节点中最小记录都会添加该标记</span> </section></td> </tr> <tr style="height: 33px;"> <td width="176" style="border-color: rgb(217, 217, 217);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">n_owned</span> </section></td> <td width="181" style="border-color: rgb(217, 217, 217);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">4</span> </section></td> <td width="332" style="border-color: rgb(217, 217, 217);"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(62, 62, 62);">当前记录拥有的记录数</span> </section></td> </tr>

面试官:什么是链路追踪?如何实现分布式链路追踪?

作者:微信小助手

<section data-mpa-powered-by="yiban.io" style="max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;margin-bottom: 0px;"> <section powered-by="xiumi.us" style="max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;"> <section style="max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;"> <section style="max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;"> <section powered-by="xiumi.us" style="max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;"> <section> <section data-mpa-powered-by="yiban.io" style="margin-bottom: 0px;outline: 0px;max-width: 100%;white-space: normal;background-color: rgb(255, 255, 255);font-size: 16px;color: rgb(62, 62, 62);line-height: 1.5;letter-spacing: 0px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <p style="margin-top: 1.7em;margin-bottom: 1.7em;outline: 0px;max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">在分布式系统,尤其是微服务系统中,一次外部请求往往需要内部多个模块,多个中间件,多台机器的相互调用才能完成。在这一系列的调用中,可能有些是串行的,而有些是并行的。在这种情况下,我们如何才能确定这整个请求调用了哪些应用?哪些模块?哪些节点?以及它们的先后顺序和各部分的性能如何呢?</p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;outline: 0px;max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">这就是涉及到链路追踪。</p> <h3 style="outline: 0px;max-width: 100%;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br mpa-from-tpl="t" style="outline: 0px;max-width: 100%;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"></h3> <section data-mpa-template="t" mpa-from-tpl="t" style="outline: 0px;max-width: 100%;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section data-mpa-template="t" mpa-from-tpl="t" style="outline: 0px;max-width: 100%;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section data-mid="" mpa-from-tpl="t" style="outline: 0px;max-width: 100%;display: flex;justify-content: center;align-items: center;width: 578px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section data-mid="" mpa-from-tpl="t" style="outline: 0px;max-width: 100%;display: flex;justify-content: flex-start;align-items: center;flex-direction: column;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section data-mid="" mpa-from-tpl="t" style="outline: 0px;max-width: 100%;z-index: 1;display: flex;justify-content: center;align-items: center;height: 36px;border-width: 1px 0px;border-top-style: dotted;border-bottom-style: dotted;border-top-color: rgb(193, 205, 249);border-bottom-color: rgb(193, 205, 249);border-left-style: initial;border-left-color: initial;border-right-style: initial;border-right-color: initial;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section data-mid="" mpa-from-tpl="t" style="outline: 0px;max-width: 100%;width: 7px;height: 9px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <img class="rich_pages wxw-img" data-ratio="1.2857142857142858" data-w="14" src="/upload/528d6047c1f8fc974a14ee4f59de28c0.png" style="outline: 0px;display: block;box-sizing: border-box !important;overflow-wrap: break-word !important;width: 14px !important;visibility: visible !important;"> </section> <section data-mid="" mpa-from-tpl="t" style="padding-right: 12px;padding-left: 12px;outline: 0px;max-width: 100%;text-align: center;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <p data-mid="" mpa-is-content="t" style="outline: 0px;max-width: 100%;font-weight: bold;color: rgb(68, 104, 248);line-height: 22px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span mpa-is-content="t" style="outline: 0px;max-width: 100%;font-size: 18px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">什么是链路追踪?</span></p> </section> <section data-mid="" mpa-from-tpl="t" style="outline: 0px;max-width: 100%;width: 7px;height: 9px;transform: rotate(180deg);visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <img data-ratio="1.2857142857142858" data-w="14" src="/upload/528d6047c1f8fc974a14ee4f59de28c0.png" style="outline: 0px;display: block;box-sizing: border-box !important;overflow-wrap: break-word !important;width: 14px !important;visibility: visible !important;"> </section> </section> </section> </section> </section> </section> <p style="outline: 0px;max-width: 100%;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br mpa-from-tpl="t" style="outline: 0px;max-width: 100%;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;outline: 0px;max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">链路追踪是分布式系统下的一个概念,它的目的就是要解决上面所提出的问题,也就是将一次分布式请求还原成调用链路,将一次分布式请求的调用情况集中展示,比如,各个服务节点上的耗时、请求具体到达哪台机器上、每个服务节点的请求状态等等。</p> </section> <p style="margin-bottom: 0px;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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);visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><img class="rich_pages wxw-img" data-ratio="0.6335952848722987" src="/upload/19992736597610b9406dcc013b9d77fc.png" data-type="png" data-w="1018" style="outline: 0px;display: initial;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 677px !important;"></p> <section style="margin-bottom: 0px;outline: 0px;max-width: 100%;white-space: normal;background-color: rgb(255, 255, 255);font-size: 16px;color: rgb(62, 62, 62);line-height: 1.5;letter-spacing: 0px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <br style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> </section> <section style="margin-bottom: 0px;outline: 0px;max-width: 100%;white-space: normal;background-color: rgb(255, 255, 255);font-size: 16px;color: rgb(62, 62, 62);line-height: 1.5;letter-spacing: 0px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <h3 style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br mpa-from-tpl="t" style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></h3> <section data-mpa-template="t" mpa-from-tpl="t" style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section data-mpa-template="t" mpa-from-tpl="t" style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section data-mid="" mpa-from-tpl="t" style="outline: 0px;max-width: 100%;display: flex;justify-content: center;align-items: center;width: 578px;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section data-mid="" mpa-from-tpl="t" style="outline: 0px;max-width: 100%;display: flex;justify-content: flex-start;align-items: center;flex-direction: column;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section data-mid="" mpa-from-tpl="t" style="outline: 0px;max-width: 100%;z-index: 1;display: flex;justify-content: center;align-items: center;height: 36px;border-width: 1px 0px;border-top-style: dotted;border-bottom-style: dotted;border-top-color: rgb(193, 205, 249);border-bottom-color: rgb(193, 205, 249);border-left-style: initial;border-left-color: initial;border-right-style: initial;border-right-color: initial;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section data-mid="" mpa-from-tpl="t" style="outline: 0px;max-width: 100%;width: 7px;height: 9px;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <img class="rich_pages wxw-img" data-ratio="1.2857142857142858" data-w="14" src="/upload/528d6047c1f8fc974a14ee4f59de28c0.png" style="outline: 0px;display: block;box-sizing: border-box !important;overflow-wrap: break-word !important;width: 14px !important;visibility: visible !important;"> </section> <section data-mid="" mpa-from-tpl="t" style="padding-right: 12px;padding-left: 12px;outline: 0px;max-width: 100%;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <p data-mid="" mpa-is-content="t" style="outline: 0px;max-width: 100%;font-weight: bold;color: rgb(68, 104, 248);line-height: 22px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span mpa-is-content="t" style="outline: 0px;max-width: 100%;font-size: 18px;box-sizing: border-box !important;overflow-wrap: break-word !important;">链路追踪的原理</span></p> </section> <section data-mid="" mpa-from-tpl="t" style="outline: 0px;max-width: 100%;width: 7px;height: 9px;transform: rotate(180deg);box-sizing: border-box !important;overflow-wrap: break-word !important;"> <img data-ratio="1.2857142857142858" data-w="14" src="/upload/528d6047c1f8fc974a14ee4f59de28c0.png" style="outline: 0px;display: block;box-sizing: border-box !important;overflow-wrap: break-word !important;width: 14px !important;visibility: visible !important;"> </section> </section> </section> </section> </section> </section> <p style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br mpa-from-tpl="t" style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;outline: 0px;max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">衡量一个接口,我们一般会看三个指标:</p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;outline: 0px;max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">1、接口的 RT(Route-Target)你怎么知道?<br style="outline: 0px;max-width: 100%;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">2、接口是否有异常响应?<br style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">3、接口请求慢在哪里?</p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;outline: 0px;max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="outline: 0px;max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">1、单体架构时代</strong></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;outline: 0px;max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;">在创业初期,我们的系统一般是单体架构,如下:</p> </section> <p style="margin-bottom: 0px;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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;"><img class="rich_pages wxw-img" data-ratio="0.32432432432432434" src="/upload/fb86404fd443504bae63af801ed53ba7.png" data-type="png" data-w="592" style="outline: 0px;display: initial;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 592px !important;"></p> <section style="margin-bottom: 0px;outline: 0px;max-width: 100%;white-space: normal;background-color: rgb(255, 255, 255);font-size: 16px;color: rgb(62, 62, 62);line-height: 1.5;letter-spacing: 0px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <p style="margin-top: 1.7em;margin-bottom: 1.7em;outline: 0px;max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;">对于单体架构,我们可以使用 AOP(切面编程)来统计这三个指标,如下:</p> </section> <p style="margin-bottom: 0px;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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;"><img class="rich_pages wxw-img" data-backh="581" data-backw="493" data-ratio="1.1784989858012171" src="/upload/b42fad4d57c9c85b8dd032d99a7404a1.png" data-type="png" data-w="493" style="outline: 0px;display: initial;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 677px !important;"></p> <section style="margin-bottom: 0px;outline: 0px;max-width: 100%;white-space: normal;background-color: rgb(255, 255, 255);font-size: 16px;color: rgb(62, 62, 62);line-height: 1.5;letter-spacing: 0px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <p style="margin-top: 1.7em;margin-bottom: 1.7em;outline: 0px;max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;">使用 AOP(切面编程),对原本的逻辑代码侵入更少,我们只需要在调用具体的业务逻辑前后分别打印一下时间即可计算出整体的调用时间。另外,使用 AOP(切面编程)来捕获异常也可知道是哪里的调用导致的异常。</p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;outline: 0px;max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="outline: 0px;max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">2、微服务架构</strong></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;outline: 0px;max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;">随着业务的快速发展,单体架构越来越不能满足需要,我们的系统慢慢会朝微服务架构发展,如下:</p> </section> <p style="margin-bottom: 0px;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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;"><img class="rich_pages wxw-img" data-ratio="0.6327608982826949" src="/upload/224f4e24abbb2b4da3153d4dcc178edb.png" data-type="png" data-w="757" style="outline: 0px;display: initial;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 677px !important;"></p> <section style="margin-bottom: 0px;outline: 0px;max-width: 100%;white-space: normal;background-color: rgb(255, 255, 255);font-size: 16px;color: rgb(62, 62, 62);line-height: 1.5;letter-spacing: 0px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <p style="margin-top: 1.7em;margin-bottom: 1.7em;outline: 0px;max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;">在微服务架构下,当有用户反馈某个页面很慢时,虽然我们知道这个请求可能的调用链是 A -----&gt; C -----&gt; B -----&gt; D,但服务这么多,而且每个服务都有好几台机器,怎么知道问题具体出在哪个服务?哪台机器呢?</p> </section> <p style="margin-bottom: 0px;outline: 0px;max-width: 100%;color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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;"><br style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p> <p style="outline: 0px;max-width: 100%;color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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;"><img class="rich_pages wxw-img" data-ratio="0.3271844660194175" src="/upload/f2117cfa41d156291b01bb9e50ec7439.png" data-type="png" data-w="1030" style="outline: 0px;letter-spacing: 0.544px;display: initial;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 677px !important;"></p> <p style="outline: 0px;max-width: 100%;color: rgb(34, 34, 34);font-family: system-ui, -apple-system, &quot;system-ui&quot;, &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;"><br style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p> <section style="margin-bottom: 0px;outline: 0px;max-width: 100%;white-space: normal;background-color: rgb(255, 255, 255);font-size: 16px;color: rgb(62, 62, 62);line-height: 1.5;letter-spacing: 0px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <p style="margin-top: 1.7em;margin-bottom: 1.7em;outline: 0px;max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">这也是微服务这种架构下的几个痛点:</strong></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;outline: 0px;max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;">1、排查问题难度大,周期长<br style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">2、特定场景难复现<br style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">3、系统性能瓶颈分析较难</p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;outline: 0px;max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;">分布式调用链就是为了解决以上几个问题而生,它主要的作用如下:</p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;outline: 0px;max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;">1、自动采取数据<br style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">2、分析数据,产生完整调用链:有了请求的完整调用链,问题有很大概率可复现<br style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">3、数据可视化:每个组件的性能可视化,能帮助我们很好地定位系统的瓶颈,及时找出问题所在</p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;outline: 0px;max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;">通过分布式追踪系统,我们能很好地定