作者:微信小助手
<h3 style=" margin-bottom: 16px;box-sizing: border-box;font-weight: 700;-webkit-tap-highlight-color: rgba(0, 0, 0, 0); line-height: 1.43;font-size: 1.5em;font-family: "Microsoft YaHei", Helvetica, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Monaco, monospace, Tahoma, STXihei, 华文细黑, STHeiti, "Helvetica Neue", "Droid Sans", "wenquanyi micro hei", FreeSans, Arimo, Arial, SimSun, 宋体, Heiti, 黑体, sans-serif;text-align: left;white-space: normal; ">Java 调试技巧</h3> <h4 style=" margin-top: 1em;margin-bottom: 16px;box-sizing: border-box;font-weight: 700;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);font-size: 1.25em; line-height: 1.4;font-family: "Microsoft YaHei", Helvetica, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Monaco, monospace, Tahoma, STXihei, 华文细黑, STHeiti, "Helvetica Neue", "Droid Sans", "wenquanyi micro hei", FreeSans, Arimo, Arial, SimSun, 宋体, Heiti, 黑体, sans-serif;text-align: left;white-space: normal; ">1、IDEA 远程调试代码</h4> <p style="margin-bottom: 16px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);font-family: "Microsoft YaHei", Helvetica, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Monaco, monospace, Tahoma, STXihei, 华文细黑, STHeiti, "Helvetica Neue", "Droid Sans", "wenquanyi micro hei", FreeSans, Arimo, Arial, SimSun, 宋体, Heiti, 黑体, sans-serif;text-align: left;white-space: normal;">在 idea 项目配置当中添加一个 Remote JVM debug,当然每个 idea 版本可能名称不一致,看准图标就行。<br style="box-sizing: border-box;"><img class="rich_pages wxw-img" data-ratio="0.47731397459165154" src="/upload/644887dfd81e4ded0a81ff57f2c78754.png" data-type="png" data-w="2204" style="box-sizing: border-box;display: inline-block;vertical-align: middle;border-width: 0px;border-style: initial;border-color: initial;cursor: zoom-in;"></p> <p style="margin-bottom: 16px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);font-family: "Microsoft YaHei", Helvetica, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Monaco, monospace, Tahoma, STXihei, 华文细黑, STHeiti, "Helvetica Neue", "Droid Sans", "wenquanyi micro hei", FreeSans, Arimo, Arial, SimSun, 宋体, Heiti, 黑体, sans-serif;text-align: left;white-space: normal;">然后配置远程服务器的地址,复制 Command line argumengts for remote JVM 下面的命令行。<br style="box-sizing: border-box;"><img class="rich_pages wxw-img" data-ratio="0.452078032230704" src="/upload/fbc72f6f9db606dc99604c64d4eaa4d9.png" data-type="png" data-w="2358" style="box-sizing: border-box;display: inline-block;vertical-align: middle;border-width: 0px;border-style: initial;border-color: initial;cursor: zoom-in;"></p> <p style="margin-bottom: 16px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);font-family: "Microsoft YaHei", Helvetica, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Monaco, monospace, Tahoma, STXihei, 华文细黑, STHeiti, "Helvetica Neue", "Droid Sans", "wenquanyi micro hei", FreeSans, Arimo, Arial, SimSun, 宋体, Heiti, 黑体, sans-serif;text-align: left;white-space: normal;">然后将项目打包,启动的时候添加上面复制的命令行。比如运行的命令是这样的:java -jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 test.jar</p> <p style="margin-bottom: 16px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);font-family: "Microsoft YaHei", Helvetica, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Monaco, monospace, Tahoma, STXihei, 华文细黑, STHeiti, "Helvetica Neue", "Droid Sans", "wenquanyi micro hei", FreeSans, Arimo, Arial, SimSun, 宋体, Heiti, 黑体, sans-serif;text-align: left;white-space: normal;">启动了远程项目,就可以本地运行调试配置了。建议不要直接调试线上项目,复制一个项目副本去调试,不然会阻塞所有线程,实在要调试的话可以配合条件调试加线程级的阻塞来测试。</p> <p style="margin-bottom: 16px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);font-family: "Microsoft YaHei", Helvetica, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Monaco, monospace, Tahoma, STXihei, 华文细黑, STHeiti, "Helvetica Neue", "Droid Sans", "wenquanyi micro hei", FreeSans, Arimo, Arial, SimSun, 宋体, Heiti, 黑体, sans-serif;text-align: left;white-space: normal;"><img class="rich_pages wxw-img" data-ratio="0.5364705882352941" src="/upload/1b30db5b9d6f95153dc85dc10a87c161.png" data-type="png" data-w="425" style="box-sizing: border-box;display: inline-block;vertical-align: middle;border-width: 0px;border-style: initial;border-color: initial;cursor: zoom-in;"></p> <h4 style=" margin-top: 1em;margin-bottom: 16px;box-sizing: border-box;font-weight: 700;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);font-size: 1.25em; line-height: 1.4;font-family: "Microsoft YaHei", Helvetica, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Monaco, monospace, Tahoma, STXihei, 华文细黑, STHeiti, "Helvetica Neue", "Droid Sans", "wenquanyi micro hei", FreeSans, Arimo, Arial, SimSun, 宋体, Heiti, 黑体, sans-serif;text-align: left;white-space: normal; ">2、jstack 调试</h4> <blockquote style="padding: 15px 20px;margin-top: 0px;margin-bottom: 16px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);color: rgb(102, 102, 102);border-left-width: 6px;border-left-color: rgb(220, 230, 240);font-size: 14px;background: rgb(242, 247, 251);font-family: "Microsoft YaHei", Helvetica, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Monaco, monospace, Tahoma, STXihei, 华文细黑, STHeiti, "Helvetica Neue", "Droid Sans", "wenquanyi micro hei", FreeSans, Arimo, Arial, SimSun, 宋体, Heiti, 黑体, sans-serif;text-align: left;white-space: normal;"> <p style="box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">jstack 是 JVM 自带的 Java 堆栈跟踪工具,用于生成 Java 虚拟机当前时刻的线程快照。线程快照是当前 Java 虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。</p> </blockquote> <p style="margin-bottom: 16px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);font-family: "Microsoft YaHei", Helvetica, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Monaco, monospace, Tahoma, STXihei, 华文细黑, STHeiti, "Helvetica Neue", "Droid Sans", "wenquanyi micro hei", FreeSans, Arimo, Arial, SimSun, 宋体, Heiti, 黑体, sans-serif;text-align: left;white-space: normal;"><span style="box-sizing: border-box;font-weight: 700;">语法</span></p> <pre style="padding: 10px;margin-bottom: 16px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);white-space: pre-wrap;overflow-wrap: break-word;font-variant-numeric: normal;font-variant-east-asian: normal;font-stretch: normal;font-size: 14.45px;line-height: 1.6;font-family: "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace;overflow: auto;background: rgb(51, 51, 51);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);text-align: left;"> <ol class="list-paddingleft-1" style="padding-left: 2.5em;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);color: rgb(255, 255, 255);"> <li style="margin-top: 6px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);list-style: decimal;"><p><code style="box-sizing: border-box;color: rgb(255, 87, 34);background: 0px 0px;border-width: initial;border-style: none;border-color: initial;font-family: "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace;font-size: 14px;border-radius: 3px;display: inline;max-width: initial;overflow: initial;line-height: inherit;overflow-wrap: normal;"><span style="box-sizing: border-box;color: rgb(1, 170, 237);">Usage</span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">:</span></code></p></li> <li style="margin-top: 6px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);list-style: decimal;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;"><p><code style="box-sizing: border-box;color: rgb(255, 87, 34);background: 0px 0px;border-width: initial;border-style: none;border-color: initial;font-family: "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace;font-size: 14px;border-radius: 3px;display: inline;max-width: initial;overflow: initial;line-height: inherit;overflow-wrap: normal;"><span style="box-sizing: border-box;color: rgb(255, 255, 255);"> jstack </span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">[-</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);">l</span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">]</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);"> </span><span style="box-sizing: border-box;color: rgb(0, 136, 0);"><pid></span></code></p></li> <li style="margin-top: 6px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);list-style: decimal;"><p><code style="box-sizing: border-box;color: rgb(255, 87, 34);background: 0px 0px;border-width: initial;border-style: none;border-color: initial;font-family: "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace;font-size: 14px;border-radius: 3px;display: inline;max-width: initial;overflow: initial;line-height: inherit;overflow-wrap: normal;"><span style="box-sizing: border-box;color: rgb(255, 255, 255);"> </span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">连接正常运行的进程</span></code></p></li> <li style="margin-top: 6px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);list-style: decimal;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;"><p><code style="box-sizing: border-box;color: rgb(255, 87, 34);background: 0px 0px;border-width: initial;border-style: none;border-color: initial;font-family: "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace;font-size: 14px;border-radius: 3px;display: inline;max-width: initial;overflow: initial;line-height: inherit;overflow-wrap: normal;"><span style="box-sizing: border-box;color: rgb(255, 255, 255);"> </span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">(</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);">to connect to running process</span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">)</span></code></p></li> <li style="margin-top: 6px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);list-style: decimal;"><p><code style="box-sizing: border-box;color: rgb(255, 87, 34);background: 0px 0px;border-width: initial;border-style: none;border-color: initial;font-family: "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace;font-size: 14px;border-radius: 3px;display: inline;max-width: initial;overflow: initial;line-height: inherit;overflow-wrap: normal;"><span style="box-sizing: border-box;color: rgb(255, 255, 255);"> jstack </span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">-</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);">F </span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">[-</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);">m</span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">]</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);"> </span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">[-</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);">l</span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">]</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);"> </span><span style="box-sizing: border-box;color: rgb(0, 136, 0);"><pid></span></code></p></li> <li style="margin-top: 6px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);list-style: decimal;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;"><p><code style="box-sizing: border-box;color: rgb(255, 87, 34);background: 0px 0px;border-width: initial;border-style: none;border-color: initial;font-family: "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace;font-size: 14px;border-radius: 3px;display: inline;max-width: initial;overflow: initial;line-height: inherit;overflow-wrap: normal;"><span style="box-sizing: border-box;color: rgb(255, 255, 255);"> </span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">连接挂起的进程</span></code></p></li> <li style="margin-top: 6px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);list-style: decimal;"><p><code style="box-sizing: border-box;color: rgb(255, 87, 34);background: 0px 0px;border-width: initial;border-style: none;border-color: initial;font-family: "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace;font-size: 14px;border-radius: 3px;display: inline;max-width: initial;overflow: initial;line-height: inherit;overflow-wrap: normal;"><span style="box-sizing: border-box;color: rgb(255, 255, 255);"> </span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">(</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);">to connect to a hung process</span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">)</span></code></p></li> <li style="margin-top: 6px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);list-style: decimal;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;"><p><code style="box-sizing: border-box;color: rgb(255, 87, 34);background: 0px 0px;border-width: initial;border-style: none;border-color: initial;font-family: "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace;font-size: 14px;border-radius: 3px;display: inline;max-width: initial;overflow: initial;line-height: inherit;overflow-wrap: normal;"><span style="box-sizing: border-box;color: rgb(255, 255, 255);"> jstack </span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">[-</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);">m</span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">]</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);"> </span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">[-</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);">l</span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">]</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);"> </span><span style="box-sizing: border-box;color: rgb(0, 136, 0);"><executable></span><span style="box-sizing: border-box;color: rgb(255, 255, 255);"> </span><span style="box-sizing: border-box;color: rgb(0, 136, 0);"><core></span></code></p></li> <li style="margin-top: 6px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);list-style: decimal;"><p><code style="box-sizing: border-box;color: rgb(255, 87, 34);background: 0px 0px;border-width: initial;border-style: none;border-color: initial;font-family: "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace;font-size: 14px;border-radius: 3px;display: inline;max-width: initial;overflow: initial;line-height: inherit;overflow-wrap: normal;"><span style="box-sizing: border-box;color: rgb(255, 255, 255);"> </span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">(</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);">to connect to a core file</span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">)</span></code></p></li> <li style="margin-top: 6px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);list-style: decimal;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;"><p><code style="box-sizing: border-box;color: rgb(255, 87, 34);background: 0px 0px;border-width: initial;border-style: none;border-color: initial;font-family: "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace;font-size: 14px;border-radius: 3px;display: inline;max-width: initial;overflow: initial;line-height: inherit;overflow-wrap: normal;"><span style="box-sizing: border-box;color: rgb(255, 255, 255);"> jstack </span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">[-</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);">m</span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">]</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);"> </span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">[-</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);">l</span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">]</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);"> </span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">[</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);">server_id@</span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">]<</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);">remote server IP </span><span style="box-sizing: border-box;color: rgb(1, 170, 237);">or</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);"> hostname</span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">></span></code></p></li> <li style="margin-top: 6px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);list-style: decimal;"><p><code style="box-sizing: border-box;color: rgb(255, 87, 34);background: 0px 0px;border-width: initial;border-style: none;border-color: initial;font-family: "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace;font-size: 14px;border-radius: 3px;display: inline;max-width: initial;overflow: initial;line-height: inherit;overflow-wrap: normal;"><span style="box-sizing: border-box;color: rgb(255, 255, 255);"> </span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">连接远程服务器</span></code></p></li> <li style="margin-top: 6px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);list-style: decimal;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;"><p><code style="box-sizing: border-box;color: rgb(255, 87, 34);background: 0px 0px;border-width: initial;border-style: none;border-color: initial;font-family: "YaHei Consolas Hybrid", Consolas, "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, monospace, monospace;font-size: 14px;border-radius: 3px;display: inline;max-width: initial;overflow: initial;line-height: inherit;overflow-wrap: normal;"><span style="box-sizing: border-box;color: rgb(255, 255, 255);"> </span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">(</span><span style="box-sizing: border-box;color: rgb(255, 255, 255);">to connect to a remote debug server</span><span style="box-sizing: border-box;color: rgb(255, 184, 0);">)</span></code></p></li> <li style="margin-top: 6px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);list-style: decimal;"><p><br></p></li> <li style="margin-top: 6px;box-sizing: border-box;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);list-style: decimal;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;backg
作者:微信小助手
<p style="text-align: center;margin-bottom: 0px;"><span style="color: rgb(115, 250, 121);">点击上方蓝字 </span><img class="rich_pages wxw-img" data-ratio="1" src="/upload/d9a2d18d22a45bf3cb8fabf91a20a184.png" data-type="png" data-w="64" style="display:inline-block;width:20px;vertical-align:text-bottom;"><span style="color: rgb(115, 250, 121);"> 关注大侠之运维</span></p> <blockquote data-tool="mdnice编辑器" data-style="border-top: none; border-right: none; border-bottom: none; font-size: 0.9em; overflow: auto; background: rgb(251, 249, 253); color: rgb(106, 115, 125); margin-bottom: 20px; margin-top: 20px; padding: 15px 20px; line-height: 27px; border-left-color: rgb(53, 179, 120);" class="js_darkmode__1" style="margin-top: 20px;margin-bottom: 20px;padding: 15px 20px;border-left-color: rgb(53, 179, 120);color: rgb(106, 115, 125);font-size: 0.9em;line-height: 27px;text-wrap: wrap;outline: 0px;border-top: none;border-right: none;border-bottom: none;background: rgb(251, 249, 253);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.544px;text-align: left;overflow: auto;visibility: visible;"> <p data-style="line-height: 26px; font-size: 15px; color: rgb(89, 89, 89);" class="js_darkmode__2" style="outline: 0px;color: rgb(89, 89, 89);line-height: 26px;font-size: 15px;visibility: visible;">大家好,这里是大侠之运维,每天分享各类干货。</p> </blockquote> <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, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;"> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;"><span style="letter-spacing: 0px;">对于一些历史docker服务,如果没有了dockerfile,你会怎么解决呢?今天推荐的这款工具就是一款可以通过现有的docker镜像然后反推出dockerfile。</span><br></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.8274253731343284" src="/upload/d62b75d4f756eec7c26cfe820449803e.png" data-type="png" data-w="1072" style="display: block;margin-right: auto;margin-left: auto;"> </figure> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 22px;"><span style="display: none;"></span><span>关于dfimage</span><span></span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">dfimage是一款用于从Docker镜像反向生成Dockerfile的开源工具,它是由LanikSJ公司开发的,使用Python语言编写。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">它可以通过访问Docker API,获取每个镜像层的元数据,然后根据元数据重建出大致的Dockerfile。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">它可以帮助用户了解和复制一个Docker镜像是如何构建的,特别是当用户没有原始的Dockerfile或者无法访问源代码仓库时。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">开源项目地址:<strong>https://github.com/LanikSJ/dfimage</strong>参考文档地址:<strong>https://laniksj.github.io/dfimage/</strong></p> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 22px;"><span style="display: none;"></span><span>dfimage 使用示例:</span><span></span></h2> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span><span>安装下载dfimage</span><span style="display: none;"></span></h3> <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("https://mmbiz.qpic.cn/mmbiz_svg/Sqqm3oJYw2iawGnJIt7eaPt55ksX2Lggpldrc0wtGnuAqbJRcAD2eYiaa6QKBQ8HBJJMA6zdLB55QSQmuDvgxrRiaicZcibBoKoqC/640?wx_fmt=svg") 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;">#使用docker pull命令从远程仓库下载ruby:latest和dfimage:latest两个镜像到本地仓库。</span><br><br>$ docker pull ruby:latest<br>latest: Pulling from library/ruby<br>...<br>Status: Downloaded newer image <span style="color: #c678dd;line-height: 26px;">for</span> ruby:latest<br><br>$ docker pull ghcr.io/laniksj/dfimage<br>Using default tag: latest<br>latest: Pulling from dfimage<br>...<br>Status: Downloaded newer image <span style="color: #c678dd;line-height: 26px;">for</span> dfimage:latest<br><br><span style="color: #5c6370;font-style: italic;line-height: 26px;"># 使用alias命令为docker run命令设置一个简单的别名,方便后续使用。</span><br><br>$ <span style="color: #e6c07b;line-height: 26px;">alias</span> dfimage=<span style="color: #98c379;line-height: 26px;">"docker run -v /var/run/docker.sock:/var/run/docker.sock --rm ghcr.io/laniksj/dfimage"</span><br><br><span style="color: #5c6370;font-style: italic;line-height: 26px;">#使用dfimage命令(即docker run命令)执行Python脚本,传入ruby:latest作为参数,输出该镜像的大致Dockerfile。</span><br><br>$ dfimage ruby:latest<br>FROM buildpack-deps:latest<br>RUN useradd -g users user<br>RUN apt-get update && apt-get install -y bison procps<br>RUN apt-get update && apt-get install -y ruby<br>ADD dir:03090a5fdc5feb8b4f1d6a69214c37b5f6d653f5185cddb6bf7fd71e6ded561c <span style="color: #c678dd;line-height: 26px;">in</span> /usr/src/ruby<br>WORKDIR /usr/src/ruby<br>RUN chown -R user:users .<br>USER user<br>RUN autoconf && ./configure --<span style="color: #e6c07b;line-height: 26px;">disable</span>-install-doc<br>RUN make -j<span style="color: #98c379;line-height: 26px;">"<span style="color: #d19a66;line-height: 26px;">$(nproc)</span>"</span><br>RUN make check<br>USER root<br>RUN apt-get purge -y ruby<br>RUN make install<br>RUN <span style="color: #e6c07b;line-height: 26px;">echo</span> <span style="color: #98c379;line-height: 26px;">'gem: --no-rdoc --no-ri'</span> >> /.gemrc<br>RUN gem install bundler<br>ONBUILD ADD . /usr/src/app<br>ONBUILD WORKDIR /usr/src/app<br>ONBUILD RUN [ ! -e Gemfile ] || bundle install --system<br> <br></code></pre> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 22px;"><span style="display: none;"></span><span>dfimage 原理</span><span></span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">该工具和docker history命令类似,都是通过访问Docker API,获取每个镜像层的元数据,然后根据元数据重建出大致的Dockerfile。</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);"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;"><strong>遍历镜像层</strong>:Python脚本会从最后一层开始,逐层遍历镜像中包含的所有层,获取每一层的元数据,其中包括生成该层的Dockerfile指令。</p> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;"><strong>遇到标签层停止</strong>:当Python脚本遇到第一个有标签的镜像层时,它会停止遍历,并输出一个FROM指令,指定该标签作为基础镜像。它假设一个有标签的镜像层代表了一个独立的镜像,有自己的Dockerfile,不需要继续反向生成。</p> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;"><strong>COPY或ADD指令不精确</strong>:如果原始的Dockerfile中使用了COPY或ADD指令,Python脚本生成的Dockerfile不会完全匹配。因为我们无法访问原始的docker build命令时使用的构建上下文,我们只能看到一些目录或文件被复制到了镜像的文件系统中(你会看到文件/目录的校验和和复制的目标路径)。</p> </section></li> </ul> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 22px;"><span style="display: none;"></span><span>dfimage亮点整理</span><span></span></h2> <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);"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;"><strong>反向生成Dockerfile</strong>:dfimage是一款用于从Docker镜像反向生成Dockerfile的开源工具,它可以帮助用户了解和复制一个Docker镜像是如何构建的,特别是当用户没有原始的Dockerfile或者无法访问源代码仓库时。</p> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;"><strong>使用Python语言编写</strong>:dfimage是使用Python语言编写的,它可以方便地与其他Python库和工具集成,比如pandas、dataframe-image等。</p> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;"><strong>支持多种后端和格式</strong>:dfimage支持使用不同的后端库来转换数据表格为图像,比如browser、matplotlib、playwright、html2image、selenium和chrome等¹。它还支持导出不同的图像格式,比如png、svg等。</p> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;"><strong>提供多种用法</strong>:dfimage提供了多种用法,比如可以在Python脚本中直接导出普通或样式化的数据表格为图像,也可以在Jupyter Notebook中将数据表格嵌入到pdf或markdown文件中,或者从一个Docker镜像中提取一个文件等。</p> </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">总之,dfimage是一款功能强大且易用的工具,它可以让用户更方便地处理和展示数据表格和Docker镜像。</p> </section>
作者:微信小助手
<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="font-size: 16px;color: black;line-height: 1.6;letter-spacing: 0px;word-break: break-word;text-align: left;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;margin-bottom: 0px;" data-mpa-powered-by="yiban.io"> <h2 data-tool="mdnice编辑器" style="font-weight: bold;font-size: 20px;margin-top: 24px;margin-bottom: 12px;text-align: justify;"><span style="color: #e7642b;text-align: center;display: block;background-color: #e7642b;color: white;padding: 3px 11px;border-radius: 1px;">?前言</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;word-spacing: 3px;letter-spacing: 1px;color: rgb(66, 75, 93);text-align: justify;">天天和数据库打交道,一天能写上几十条 SQL 语句,但你知道我们的系统是如何和数据库交互的吗?MySQL 如何帮我们存储数据、又是如何帮我们管理事务?....是不是感觉真的除了写几个 「select * from dual」外基本脑子一片空白?这篇文章就将带你走进 MySQL 的世界,让你彻底了解系统到底是如何和 MySQL 交互的,MySQL 在接受到我们发送的 SQL 语句时又分别做了哪些事情。</p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;font-size: 20px;margin-top: 24px;margin-bottom: 12px;text-align: justify;"><span style="display: none;"></span><span style="color: #e7642b;text-align: center;display: block;background-color: #e7642b;color: white;padding: 3px 11px;border-radius: 1px;">MySQL 驱动</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;word-spacing: 3px;letter-spacing: 1px;color: rgb(66, 75, 93);text-align: justify;">我们的系统在和 MySQL 数据库进行通信的时候,总不可能是平白无故的就能接收和发送请求,就算是你没有做什么操作,那总该是有其他的“人”帮我们做了一些事情,基本上使用过 MySQL 数据库的程序员多多少少都会知道 MySQL 驱动这个概念的。就是这个 MySQL 驱动在底层帮我们做了对数据库的连接,只有建立了连接了,才能够有后面的交互。看下图表示</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img data-ratio="0.30454545454545456" src="/upload/7eeeb54467dbf69c11677fd3a8f086bc.png" data-type="png" data-w="660" style="display: block;border-radius: 5px;margin: 12px auto;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;word-spacing: 3px;letter-spacing: 1px;color: rgb(66, 75, 93);text-align: justify;">这样的话,在系统和 MySQL 进行交互之前,MySQL 驱动会帮我们建立好连接,然后我们只需要发送 SQL 语句就可以执行 CRUD 了。一次 SQL 请求就会建立一个连接,多个请求就会建立多个连接,那么问题来了,我们系统肯定不是一个人在使用的,换句话说肯定是存在多个请求同时去争抢连接的情况。我们的 web 系统一般都是部署在 tomcat 容器中的,而 tomcat 是可以并发处理多个请求的,这就会导致多个请求会去建立多个连接,然后使用完再都去关闭,这样会有什么问题呢?如下图</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;word-spacing: 3px;letter-spacing: 1px;color: rgb(66, 75, 93);text-align: justify;"><img data-ratio="0.3692493946731235" src="/upload/1eb94fb5f21b172961bbbb279e4463db.png" data-type="png" data-w="826" style="display: block;border-radius: 5px;margin: 12px auto;"></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;word-spacing: 3px;letter-spacing: 1px;color: rgb(66, 75, 93);text-align: justify;">java 系统在通过 MySQL 驱动和 MySQL 数据库连接的时候是基于 TCP/IP 协议的,所以如果每个请求都是新建连接和销毁连接,那这样势必会造成不必要的浪费和性能的下降,也就说上面的多线程请求的时候频繁的创建和销毁连接显然是不合理的。必然会大大降低我们系统的性能,但是如果给你提供一些固定的用来连接的线程,这样是不是不需要反复的创建和销毁连接了呢?相信懂行的朋友会会心一笑,没错,说的就是数据库连接池。</p> <blockquote data-tool="mdnice编辑器" style="font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);padding: 10px 10px 10px 20px;margin: 0px 8px;border-width: initial;border-style: none;border-color: initial;background: rgb(255, 255, 255);box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 2px -2px, rgba(0, 0, 0, 0.12) 0px 3px 6px 0px, rgba(0, 0, 0, 0.09) 0px 5px 12px 4px;"> <p style="padding-top: 8px;padding-bottom: 8px;word-spacing: 3px;letter-spacing: 1px;font-size: 14px;color: rgb(66, 75, 93);line-height: 24px;text-align: justify;">数据库连接池:维护一定的连接数,方便系统获取连接,使用就去池子中获取,用完放回去就可以了,我们不需要关心连接的创建与销毁,也不需要关心线程池是怎么去维护这些连接的。</p> </blockquote> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;word-spacing: 3px;letter-spacing: 1px;color: rgb(66, 75, 93);text-align: justify;"><img data-ratio="0.3612078977932636" src="/upload/6741d87b1ea9255fca882c29733aadf1.png" data-type="png" data-w="861" style="display: block;border-radius: 5px;margin: 12px auto;">常见的数据库连接池有 <code style="font-size: 14px;padding-top: 2px;padding-bottom: 2px;margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;border-radius: 0px;color: rgb(235, 97, 97);border-bottom: 1px solid rgb(235, 97, 97);">Druid、C3P0、DBCP</code>,连接池实现原理在这里就不深入讨论了,采用连接池大大节省了不断创建与销毁线程的开销,这就是有名的「池化」思想,不管是线程池还是 HTTP 连接池,都能看到它的身影。</p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;font-size: 20px;margin-top: 24px;margin-bottom: 12px;text-align: justify;"><span style="display: none;"></span><span style="color: #e7642b;text-align: center;display: block;background-color: #e7642b;color: white;padding: 3px 11px;border-radius: 1px;">数据库连接池</span></h2> <p data-
作者:微信小助手
<section class="mp_profile_iframe_wrp" data-mpa-powered-by="yiban.io"> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-id="Mzg4NjYyODc4OA==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/J4jTHmo8Xh6qM32ASOtVbXNoiaegrI26qLRw6r6FTI7dZw6TMT7vecvnjd1O8xSsM5MiajIuQZicxSC6KFK8TMpbg/0?wx_fmt=png" data-nickname="java突击队" data-alias="" data-signature="技术经验分享" data-from="0" data-is_biz_ban="0"></mp-common-profile> </section> <section style=""> 今天分享一篇SQL优化的文章~ </section> <section style=""> <span style="outline: 0px;font-style: inherit;word-spacing: 2px;widows: 1;white-space-collapse: preserve-breaks;border-width: 0px;border-style: initial;border-color: initial;font-variant: inherit;font-stretch: inherit;line-height: inherit;font-family: PingFangSC-Regular;vertical-align: baseline;color: rgb(136, 136, 136);visibility: visible;letter-spacing: 1px;"> </span> </section> <section style=""> <strong style="outline: 0px;color: rgb(171, 25, 66);font-size: 20px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, Cambria, Cochin, Georgia, Times, serif;letter-spacing: 0px;text-align: left;">场景</strong> </section> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="margin-bottom: 0px;padding-right: 10px;padding-left: 10px;outline: 0px;background-color: rgb(255, 255, 255);font-size: 16px;color: black;line-height: 1.6;letter-spacing: 0px;word-break: break-word;text-align: left;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, Cambria, Cochin, Georgia, Times, serif;"> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">用的数据库是mysql5.6,下面简单的介绍下场景。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;"><strong style="outline: 0px;">课程表</strong></p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">create table Course(<br style="outline: 0px;">c_id int PRIMARY KEY,<br style="outline: 0px;">name varchar(10)<br style="outline: 0px;">)<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">数据100条。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;"><strong style="outline: 0px;">学生表</strong></p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">create table Student(<br style="outline: 0px;">id int PRIMARY KEY,<br style="outline: 0px;">name varchar(10)<br style="outline: 0px;">)<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">数据70000条。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;"><strong style="outline: 0px;">学生成绩表</strong></p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">CREATE table SC(<br style="outline: 0px;"> sc_id int PRIMARY KEY, <br style="outline: 0px;"> s_id int, <br style="outline: 0px;"> c_id int, <br style="outline: 0px;"> score int<br style="outline: 0px;">)<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">数据70w条。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;"><strong style="outline: 0px;">查询目的:</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">查找语文考100分的考生。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;"><strong style="outline: 0px;">查询语句:</strong></p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">select s.* from Student s<br style="outline: 0px;"><span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">where</span> s.s_id <span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">in</span> ( <br style="outline: 0px;"> select s_id <br style="outline: 0px;"> from SC sc <br style="outline: 0px;"> <span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">where</span> sc.c_id = 0 and sc.score = 100 )<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;"><strong style="outline: 0px;">执行时间:30248.271s</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">晕,为什么这么慢,先来查看下查询计划:</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">EXPLAIN<br style="outline: 0px;">select s.* from Student s <br style="outline: 0px;"> <span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">where</span> s.s_id <span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">in</span> ( <br style="outline: 0px;"> select s_id <br style="outline: 0px;"> from SC sc <br style="outline: 0px;"> <span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">where</span> sc.c_id = 0 and sc.score = 100 )<br style="outline: 0px;"></code></pre> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.08300395256916997" src="/upload/ab49fc94fb8f01c67d95a8c4d4441782.png" data-type="png" data-w="759" style="margin-right: auto;margin-left: auto;outline: 0px;vertical-align: inherit;display: block;visibility: visible !important;width: 677px !important;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">发现没有用到索引,type全是ALL,那么首先想到的就是建立一个索引,建立索引的字段当然是在where条件的字段。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">先给sc表的c_id和score建个索引。</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">CREATE index sc_c_id_index on SC(c_id);<br style="outline: 0px;">CREATE index sc_score_index on SC(score);<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">再次执行上述查询语句,时间为: <strong style="outline: 0px;">1.054s</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">快了3w多倍,大大缩短了查询时间,看来索引能极大程度的提高查询效率,建索引很有必要,很多时候都忘记建。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">索引了,数据量小的的时候压根没感觉,这优化的感觉挺爽。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">但是1s的时间还是太长了,还能进行优化吗,仔细看执行计划:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.07416563658838071" data-type="png" data-w="809" src="/upload/998748dc146f9ca266b7c4066971ad63.png" style="margin-right: auto;margin-left: auto;outline: 0px;vertical-align: inherit;border-radius: 8px;display: block;background-size: 16px !important;width: 657px !important;visibility: visible !important;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">查看优化后的sql:</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">SELECT<br style="outline: 0px;"> `YSB`.`s`.`s_id` AS `s_id`, <br style="outline: 0px;"> `YSB`.`s`.`name` AS `name`<br style="outline: 0px;">FROM <br style="outline: 0px;"> `YSB`.`Student` `s`<br style="outline: 0px;">WHERE <br style="outline: 0px;"> < in_optimizer > ( <br style="outline: 0px;"> `YSB`.`s`.`s_id` ,< EXISTS > ( <br style="outline: 0px;"> SELECT <br style="outline: 0px;"> 1 <br style="outline: 0px;"> FROM <br style="outline: 0px;"> `YSB`.`SC` `sc` <br style="outline: 0px;"> WHERE <br style="outline: 0px;"> ( <br style="outline: 0px;"> (`YSB`.`sc`.`c_id` = 0) <br style="outline: 0px;"> AND (`YSB`.`sc`.`score` = 100) <br style="outline: 0px;"> AND ( <br style="outline: 0px;"> < CACHE > (`YSB`.`s`.`s_id`) = `YSB`.`sc`.`s_id` <br style="outline: 0px;"> ) <br style="outline: 0px;"> ) <br style="outline: 0px;"> ) <br style="outline: 0px;"> )<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">补充:这里有网友问怎么查看优化后的语句。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">方法如下:</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">在命令窗口执行</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.5" data-type="png" data-w="422" src="/upload/aac07b40f060462150bb4f85f96b0fd3.png" style="margin-right: auto;margin-left: auto;outline: 0px;vertical-align: inherit;display: block;visibility: visible !important;width: 422px !important;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;"><strong style="outline: 0px;">有type=all</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">按照我之前的想法,该sql的执行的顺序应该是先执行子查询。</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">select s_id<br style="outline: 0px;">from SC sc <br style="outline: 0px;"><span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">where</span> sc.c_id = 0 and sc.score = 100<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;"><strong style="outline: 0px;">耗时:0.001s</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">得到如下结果:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.9117647058823529" src="/upload/94928e0936a8172c85a1dc04123fabc1.png" data-type="png" data-w="102" style="margin-right: auto;margin-left: auto;outline: 0px;vertical-align: inherit;border-radius: 8px;display: block;background-size: 16px !important;width: 102px !important;visibility: visible !important;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">然后再执行</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">select s.* <br style="outline: 0px;">from Student s <br style="outline: 0px;"><span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">where</span> s.s_id <span style="outline: 0px;color: rgb(198, 120, 221);line-height: 26px;">in</span>(7,29,5000)<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;"><strong style="outline: 0px;">耗时:0.001s</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">这样就是相当快了啊,Mysql竟然不是先执行里层的查询,而是将sql优化成了exists子句,并出现了EPENDENT SUBQUERY,</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">mysql是先执行外层查询,再执行里层的查询,这样就要循环70007*8次。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">那么改用连接查询呢?</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">SELECT s.* from<br style="outline: 0px;">Student s<br style="outline: 0px;">INNER JOIN SC sc<br style="outline: 0px;">on sc.s_id = s.s_id<br style="outline: 0px;"><span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">where</span> sc.c_id=0 and sc.score=100<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">这里为了重新分析连接查询的情况,先暂时删除索引<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;outline: 0px;font-size: 14px;word-break: break-all;border-radius: 4px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);font-family: Consolas, Monaco, Menlo, monospace;">sc_c_id_index,sc_score_index</code> 。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;"><strong style="outline: 0px;">执行时间是:0.057s</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">效率有所提高,看看执行计划:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.10497981157469717" data-type="png" data-w="743" src="/upload/4f0a9bd8a0e7a3c6dea3f1232ea59236.png" style="margin-right: auto;margin-left: auto;outline: 0px;vertical-align: inherit;display: block;visibility: visible !important;width: 677px !important;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">这里有连表的情况出现,我猜想是不是要给sc表的s_id建立个索引</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">CREATE index sc_s_id_index on SC(s_id);<br style="outline: 0px;">show index from SC<br style="outline: 0px;"></code></pre> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.2915129151291513" data-type="png" data-w="271" src="/upload/75f872fc5ec172c036f3c6fd290c156d.png" style="margin-right: auto;margin-left: auto;outline: 0px;vertical-align: inherit;display: block;visibility: visible !important;width: 271px !important;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">在执行连接查询</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;"><strong style="outline: 0px;">时间: 1.076s,</strong> 竟然时间还变长了,什么原因?查看执行计划:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.1" data-type="png" data-w="760" src="/upload/a9fe2713bf88300a6d864bb1ccee8437.png" style="margin-right: auto;margin-left: auto;outline: 0px;vertical-align: inherit;display: block;visibility: visible !important;width: 677px !important;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">优化后的查询语句为:</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">SELECT <br style="outline: 0px;"> `YSB`.`s`.`s_id` AS `s_id`, <br style="outline: 0px;"> `YSB`.`s`.`name` AS `name`<br style="outline: 0px;">FROM <br style="outline: 0px;"> `YSB`.`Student` `s`<br style="outline: 0px;">JOIN `YSB`.`SC` `sc`<br style="outline: 0px;">WHERE <br style="outline: 0px;"> ( <br style="outline: 0px;"> ( <br style="outline: 0px;"> `YSB`.`sc`.`s_id` = `YSB`.`s`.`s_id` <br style="outline: 0px;"> ) <br style="outline: 0px;"> AND (`YSB`.`sc`.`score` = 100) <br style="outline: 0px;"> AND (`YSB`.`sc`.`c_id` = 0) <br style="outline: 0px;"> )<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">貌似是先做的连接查询,再进行的where条件过滤。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;"><strong style="outline: 0px;">回到前面的执行计划:</strong></p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.10497981157469717" src="/upload/4f0a9bd8a0e7a3c6dea3f1232ea59236.png" data-type="png" data-w="743" style="margin-right: auto;margin-left: auto;outline: 0px;vertical-align: inherit;display: block;visibility: visible !important;width: 677px !important;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">这里是先做的where条件过滤,再做连表,执行计划还不是固定的,那么我们先看下标准的sql执行顺序:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.9449275362318841" data-type="png" data-w="345" src="/upload/7096490669f4cfdce273a9a838e30328.png" style="margin-right: auto;margin-left: auto;outline: 0px;vertical-align: inherit;display: block;visibility: visible !important;width: 345px !important;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">正常情况下是先join再进行where过滤,但是我们这里的情况,如果先join,将会有70w条数据发送join做操,因此先执行where 。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">过滤是明智方案,现在为了排除mysql的查询优化,我自己写一条优化后的sql 。</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">SELECT <br style="outline: 0px;"> s.*<br style="outline: 0px;">FROM <br style="outline: 0px;"> ( <br style="outline: 0px;"> SELECT <br style="outline: 0px;"> * <br style="outline: 0px;"> FROM <br style="outline: 0px;"> SC sc <br style="outline: 0px;"> WHERE <br style="outline: 0px;"> sc.c_id = 0 <br style="outline: 0px;"> AND sc.score = 100 <br style="outline: 0px;"> ) t<br style="outline: 0px;">INNER JOIN Student s ON t.s_id = s.s_id<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">即先执行sc表的过滤,再进行表连接,<strong style="outline: 0px;">执行时间为:0.054s</strong> 。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">和之前没有建s_id索引的时间差不多。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">查看执行计划:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.12610340479192939" data-type="png" data-w="793" src="/upload/86ba3ba027ed7af2b9c7d9200da986c0.png" style="margin-right: auto;margin-left: auto;outline: 0px;vertical-align: inherit;border-radius: 8px;display: block;background-size: 16px !important;width: 657px !important;visibility: visible !important;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">先提取sc再连表,这样效率就高多了,现在的问题是提取sc的时候出现了扫描表,那么现在可以明确需要建立相关索引。</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">CREATE index sc_c_id_index on SC(c_id);<br style="outline: 0px;">CREATE index sc_score_index on SC(score);<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">再执行查询:</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">SELECT <br style="outline: 0px;"> s.*<br style="outline: 0px;">FROM <br style="outline: 0px;"> ( <br style="outline: 0px;"> SELECT <br style="outline: 0px;"> * <br style="outline: 0px;"> FROM <br style="outline: 0px;"> SC sc <br style="outline: 0px;"> WHERE <br style="outline: 0px;"> sc.c_id = 0 <br style="outline: 0px;"> AND sc.score = 100 <br style="outline: 0px;"> ) t<br style="outline: 0px;">INNER JOIN Student s ON t.s_id = s.s_id<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;"><strong style="outline: 0px;">执行时间为:0.001s</strong>,这个时间相当靠谱,快了50倍。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">执行计划:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.12763320941759604" data-type="png" data-w="807" src="/upload/59e8cc49ae17a125e3806ffa5c4282fc.png" style="margin-right: auto;margin-left: auto;outline: 0px;vertical-align: inherit;display: block;visibility: visible !important;width: 677px !important;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">我们会看到,先提取sc,再连表,都用到了索引。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">那么再来执行下sql。</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">SELECT s.* from<br style="outline: 0px;">Student s<br style="outline: 0px;">INNER JOIN SC sc<br style="outline: 0px;">on sc.s_id = s.s_id<br style="outline: 0px;"><span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">where</span> sc.c_id=0 and sc.score=100<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;"><strong style="outline: 0px;">执行时间0.001s</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">执行计划:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.08035714285714286" data-type="png" data-w="896" src="/upload/1d7feed56681d6d32bee14f86148d2e2.png" style="margin-right: auto;margin-left: auto;outline: 0px;vertical-align: inherit;display: block;visibility: visible !important;width: 677px !important;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">这里是mysql进行了查询语句优化,先执行了where过滤,再执行连接操作,且都用到了索引。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">补充:最近又重新导入一些生产数据,经测试发现,前几天优化完的sql执行效率又变低了。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">调整内容为SC表的数据增长到300W,学生分数更为离散。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">先回顾下:</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;"><code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;outline: 0px;font-size: 14px;word-break: break-all;border-radius: 4px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);font-family: Consolas, Monaco, Menlo, monospace;">show index from SC</code></p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.19480519480519481" data-type="png" data-w="539" src="/upload/2e7ccc8568da7c2787c4de591f9be66a.png" style="margin-right: auto;margin-left: auto;outline: 0px;vertical-align: inherit;border-radius: 8px;display: block;background-size: 16px !important;width: 539px !important;visibility: visible !important;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;"><strong style="outline: 0px;">执行sql</strong></p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">SELECT s.* from<br style="outline: 0px;">Student s<br style="outline: 0px;">INNER JOIN SC sc<br style="outline: 0px;">on sc.s_id = s.s_id<br style="outline: 0px;"><span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">where</span> sc.c_id=81 and sc.score=84<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;"><strong style="outline: 0px;">执行时间:0.061s</strong>,这个时间稍微慢了点。执行计划:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.08250825082508251" data-type="png" data-w="909" src="/upload/758f66bf3d50b493510a1617b3673dfc.png" style="margin-right: auto;margin-left: auto;outline: 0px;vertical-align: inherit;display: block;visibility: visible !important;width: 677px !important;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">这里用到了intersect并集操作,即两个索引同时检索的结果再求并集,再看字段score和c_id的区分度。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">单从一个字段看,区分度都不是很大,从SC表检索,<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;outline: 0px;font-size: 14px;word-break: break-all;border-radius: 4px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);font-family: Consolas, Monaco, Menlo, monospace;">c_id=81</code>检索的结果是70001,<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;outline: 0px;font-size: 14px;word-break: break-all;border-radius: 4px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);font-family: Consolas, Monaco, Menlo, monospace;">score=84</code>的结果是39425。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">而<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;outline: 0px;font-size: 14px;word-break: break-all;border-radius: 4px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);font-family: Consolas, Monaco, Menlo, monospace;">c_id=81 and score=84</code> 的结果是897,即这两个字段联合起来的区分度是比较高的,因此建立联合索引查询效率。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">将会更高,从另外一个角度看,该表的数据是300w,以后会更多,就索引存储而言,都是不小的数目,随着数据量的<span style="outline: 0px;letter-spacing: 0px;">增</span>加<span style="outline: 0px;letter-spacing: 0px;">,索引就不能全部加载到内存,而是要从磁盘去读取,这样索引的个数越多,读磁盘的开销就越大,因此根据具体。</span></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">业务情况建立多列的联合索引是必要的,那么我们来试试吧。</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">alter table SC drop index sc_c_id_index;<br style="outline: 0px;">alter table SC drop index sc_score_index;<br style="outline: 0px;">create index sc_c_id_score_index on SC(c_id,score);<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">执行上述查询语句,<strong style="outline: 0px;">消耗时间为:0.007s</strong>,这个速度还是可以接受的。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">执行计划:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.09318181818181819" data-type="png" data-w="880" src="/upload/e0a78696dc41e82c40f3ce1e1b7a703c.png" style="margin-right: auto;margin-left: auto;outline: 0px;vertical-align: inherit;border-radius: 8px;display: block;background-size: 16px !important;width: 657px !important;visibility: visible !important;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">该语句的优化暂时告一段落。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;outline: 0px;font-size: 20px;"><span style="outline: 0px;font-size: 18px;color: rgb(61, 167, 66);"><strong style="outline: 0px;">总结</strong></span></h3> <ol data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 30px;outline: 0px;"> <li style="outline: 0px;"> <section style="margin-top: 5px;margin-bottom: 5px;outline: 0px;line-height: 26px;color: rgb(1, 1, 1);"> mysql嵌套子查询效率确实比较低 </section></li> <li style="outline: 0px;"> <section style="margin-top: 5px;margin-bottom: 5px;outline: 0px;line-height: 26px;color: rgb(1, 1, 1);"> 可以将其优化成连接查询 </section></li> <li style="outline: 0px;"> <section style="margin-top: 5px;margin-bottom: 5px;outline: 0px;line-height: 26px;color: rgb(1, 1, 1);"> 连接表时,可以先用where条件对表进行过滤,然后做表连接 <br style="outline: 0px;">(虽然mysql会对连表语句做优化) </section></li> <li style="outline: 0px;"> <section style="margin-top: 5px;margin-bottom: 5px;outline: 0px;line-height: 26px;color: rgb(1, 1, 1);"> 建立合适的索引,必要时建立多列联合索引 </section></li> <li style="outline: 0px;"> <section style="margin-top: 5px;margin-bottom: 5px;outline: 0px;line-height: 26px;color: rgb(1, 1, 1);"> 学会分析sql执行计划,mysql会对sql进行优化,所以分析执行计划很重要 </section></li> </ol> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;outline: 0px;font-size: 22px;"><span style="outline: 0px;font-size: 20px;color: rgb(171, 25, 66);"><strong style="outline: 0px;">索引优化</strong></span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">上面讲到子查询的优化,以及如何建立索引,而且在多个字段索引时,分别对字段建立了单个索引。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">后面发现其实建立联合索引效率会更高,尤其是在数据量较大,单个列区分度不高的情况下。</p> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;outline: 0px;font-size: 22px;"><span style="outline: 0px;font-size: 20px;color: rgb(171, 25, 66);"><strong style="outline: 0px;">单列索引</strong></span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">查询语句如下:</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">select * from user_test_copy <span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">where</span> sex = 2 and <span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">type</span> = 2 and age = 10<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">索引:</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">CREATE index user_test_index_sex on user_test_copy(sex);<br style="outline: 0px;">CREATE index user_test_index_type on user_test_copy(<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">type</span>);<br style="outline: 0px;">CREATE index user_test_index_age on user_test_copy(age);<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">分别对sex,type,age字段做了索引,数据量为300w,<strong style="outline: 0px;">查询时间:0.415s</strong>执行计划:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.09706546275395034" data-type="png" data-w="886" src="/upload/b1baaced3812cf0491d42d53555c7c19.png" style="margin-right: auto;margin-left: auto;outline: 0px;vertical-align: inherit;display: block;visibility: visible !important;width: 677px !important;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">发现 <code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;outline: 0px;font-size: 14px;word-break: break-all;border-radius: 4px;color: rgb(233, 105, 0);background: rgb(248, 248, 248);font-family: Consolas, Monaco, Menlo, monospace;">type=index_merge</code></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">这是mysql对多个单列索引的优化,对结果集采用intersect并集操作</p> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;outline: 0px;font-size: 22px;"><span style="outline: 0px;font-size: 20px;color: rgb(171, 25, 66);"><strong style="outline: 0px;">多列索引</strong></span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">我们可以在这3个列上建立多列索引,将表copy一份以便做测试</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">create index user_test_index_sex_type_age on user_test(sex,<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">type</span>,age);<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">查询语句:</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">select * from user_test <span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">where</span> sex = 2 and <span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">type</span> = 2 and age = 10<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">执行时间:0.032s,快了10多倍,且多列索引的区分度越高,提高的速度也越多</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">执行计划:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-ratio="0.06040268456375839" data-type="png" data-w="894" src="/upload/cba15adc2cb49e6122f8c08dd6bb94b.png" style="margin-right: auto;margin-left: auto;outline: 0px;vertical-align: inherit;display: block;visibility: visible !important;width: 677px !important;height: auto !important;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;"><strong style="outline: 0px;">最左前缀</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">多列索引还有最左前缀的特性:</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">执行以下语句:</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">select * from user_test <span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">where</span> sex = 2<br style="outline: 0px;">select * from user_test <span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">where</span> sex = 2 and <span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">type</span> = 2<br style="outline: 0px;">select * from user_test <span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">where</span> sex = 2 and age = 10<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">都会使用到索引,即索引的第一个字段sex要出现在where条件中</p> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;outline: 0px;font-size: 22px;"><span style="outline: 0px;font-size: 20px;color: rgb(171, 25, 66);"><strong style="outline: 0px;">索引覆盖</strong></span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">就是查询的列都建立了索引,这样在获取结果集的时候不用再去磁盘获取其它列的数据,直接返回索引数据即可</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">如:</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">select sex,<span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">type</span>,age from user_test <span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">where</span> sex = 2 and <span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">type</span> = 2 and age = 10<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;"><strong style="outline: 0px;">执行时间:0.003s</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">要比取所有字段快的多</p> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;outline: 0px;font-size: 22px;"><span style="outline: 0px;font-size: 20px;color: rgb(171, 25, 66);"><strong style="outline: 0px;">排序</strong></span></h2> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">select * from user_test <span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">where</span> sex = 2 and <span style="outline: 0px;color: rgb(230, 192, 123);line-height: 26px;">type</span> = 2 ORDER BY user_name<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;"><strong style="outline: 0px;">时间:0.139s</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">在排序字段上建立索引会提高排序的效率</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;outline: 0px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><code style="padding: 15px 16px 16px;outline: 0px;overflow-x: auto;color: rgb(171, 178, 191);display: -webkit-box;font-size: 12px;background: rgb(40, 44, 52);border-radius: 5px;font-family: Consolas, Monaco, Menlo, monospace;">create index user_name_index on user_test(user_name)<br style="outline: 0px;"></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;">最后附上一些sql调优的总结,以后有时间再深入研究</p> <ol data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 30px;outline: 0px;"> <li style="outline: 0px;"> <section style="margin-top: 5px;margin-bottom: 5px;outline: 0px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;color: black;">列类型尽量定义成数值类型,且长度尽可能短,如主键和外键,类型字段等等</p> </section></li> <li style="outline: 0px;"> <section style="margin-top: 5px;margin-bottom: 5px;outline: 0px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;color: black;">建立单列索引</p> </section></li> <li style="outline: 0px;"> <section style="margin-top: 5px;margin-bottom: 5px;outline: 0px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;color: black;">根据需要建立多列联合索引<br style="outline: 0px;">当单个列过滤之后还有很多数据,那么索引的效率将会比较低,即列的区分度较低,<br style="outline: 0px;">那么如果在多个列上建立索引,那么多个列的区分度就大多了,将会有显著的效率提高。</p> </section></li> <li style="outline: 0px;"> <section style="margin-top: 5px;margin-bottom: 5px;outline: 0px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;color: black;">根据业务场景建立覆盖索引<br style="outline: 0px;">只查询业务需要的字段,如果这些字段被索引覆盖,将极大的提高查询效率</p> </section></li> <li style="outline: 0px;"> <section style="margin-top: 5px;margin-bottom: 5px;outline: 0px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;color: black;">多表连接的字段上需要建立索引 这样可以极大的提高表连接的效率</p> </section></li> <li style="outline: 0px;"> <section style="margin-top: 5px;margin-bottom: 5px;outline: 0px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;color: black;">where条件字段上需要建立索引</p> </section></li> <li style="outline: 0px;"> <section style="margin-top: 5px;margin-bottom: 5px;outline: 0px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;color: black;">排序字段上需要建立索引</p> </section></li> <li style="outline: 0px;"> <section style="margin-top: 5px;margin-bottom: 5px;outline: 0px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;color: black;">分组字段上需要建立索引</p> </section></li> <li style="outline: 0px;"> <section style="margin-top: 5px;margin-bottom: 5px;outline: 0px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;outline: 0px;line-height: 26px;color: black;">Where条件上不要使用运算函数,以免索引失效</p> </section></li> </ol> </section> <p style="margin-bottom: 0px;outline: 0px;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);color: rgba(0, 0, 0, 0.5);font-family: -apple-system-font, system-ui, Arial, sans-serif;font-size: 15px;caret-color: rgb(0, 0, 0);text-align: right;"><span style="outline: 0px;font-size: 12px;">来源:</span><span style="font-size: 12px;letter-spacing: 0.544px;">cnblogs.com/tangyanbo/p/4462734.html</span></p> <p style="margin-bottom: 0px;outline: 0px;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);color: rgba(0, 0, 0, 0.5);font-family: -apple-system-font, system-ui, Arial, sans-serif;font-size: 15px;caret-color: rgb(0, 0, 0);text-align: right;"><span style="font-size: 12px;letter-spacing: 0.544px;"><br></span></p> <section class="mp_profile_iframe_wrp"> <mp-common-profile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-id="Mzg4NjYyODc4OA==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/J4jTHmo8Xh6qM32ASOtVbXNoiaegrI26qLRw6r6FTI7dZw6TMT7vecvnjd1O8xSsM5MiajIuQZicxSC6KFK8TMpbg/0?wx_fmt=png" data-nickname="java突击队" data-alias="" data-signature="技术经验分享" data-from="0" data-is_biz_ban="0"></mp-common-profile> </section> <section> <span style="font-size: 12px;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);color: rgba(0, 0, 0, 0.5);font-family: -apple-system-font, system-ui, Arial, sans-serif;text-align: right;caret-color: rgb(0, 0, 0);"></span> </section> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>
作者:微信小助手
<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="color: black;letter-spacing: 0px;white-space: normal;font-size: 16px;padding-right: 10px;padding-left: 10px;line-height: 1.6;word-break: break-word;text-align: left;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;margin-bottom: 24px;" data-mpa-powered-by="yiban.io"> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">为了节省大家的时间,阿Q决定帮大家先将 MySQL 面试相关的知识进行汇总整理,一改往日知识点东一棒槌西一榔头的问题。那么,你准备好迎接 MySQL 连环炮了嘛?</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;"><br></p> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li><p>1、三大范式</p></li> <li><p>2、DML 语句和 DDL 语句区别</p></li> <li><p>3、主键和外键的区别</p></li> <li><p>4、drop、delete、truncate 区别</p></li> <li><p>5、基础架构</p></li> <li><p>6、MyISAM 和 InnoDB 有什么区别?</p></li> <li><p>7、推荐自增id作为主键问题</p></li> <li><p>8、为什么 MySQL 的自增主键不连续</p></li> <li><p>9、redo log 是做什么的?</p></li> <li><p>10、redo log 的刷盘时机</p></li> <li><p>11、redo log 是怎么记录日志的</p></li> <li><p>12、什么是 binlog</p></li> <li><p>13、binlog 记录格式</p></li> <li><p>14、binlog 写入机制</p></li> <li><p>15、redolog 和 binlog 的区别是什么</p></li> <li><p>16、两阶段提交</p></li> <li><p>17、什么是 undo log.</p></li> <li><p>18、什么是 relaylog</p></li> <li><p>19、索引</p></li> <li><p>20、Hash 索引</p></li> <li><p>21、B树和B+ 树</p></li> <li><p>22、主键索引</p></li> <li><p>23、二级索引</p></li> <li><p>24、聚簇索引与非聚簇索引</p></li> <li><p>25、回表</p></li> <li><p>26、覆盖索引和联合索引</p></li> <li><p>27、最左前缀匹配原则</p></li> <li><p>28、索引下推</p></li> <li><p>29、隐式转换</p></li> <li><p>30、普通索引和唯一索引该怎么选择?</p></li> <li><p>31、避免索引失效</p></li> <li><p>32、建立索引的规则</p></li> <li><p>33、事务极其特性</p></li> <li><p>34、并发事务带来的问题</p></li> <li><p>35、事务的隔离级别</p></li> <li><p>36、MVCC</p></li> <li><p>37、Mysql 中的锁</p></li> <li><p>38、查询语句执行过程</p></li> <li><p>39、更新语句执行过程</p></li> <li><p>40、sql 优化</p></li> <li><p>41、主从同步数据</p></li> <li><p>42、主从延迟要怎么解决</p></li> <li><p>43、为什么不要使用长事务</p></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;"><br></p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;">1、三大范式</h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">1NF(第一范式):属性(对应于表中的字段)不能再被分割,也就是这个字段只能是一个值,不能再分为多个其他的字段了。<strong>1NF 是所有关系型数据库的最基本要求</strong> ,也就是说关系型数据库中创建的表一定满足第一范式。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">2NF(第二范式):2NF 要求数据库表中的每个实例或行必须<strong>可以被惟一地区分</strong>,2NF 在 1NF 的基础上增加了一个列,这个列称为主键,非主属性都依赖于主键。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">3NF(第三范式):3NF 在 2NF 的基础之上,要求每列都和主键列直接相关,而不是间接相关,即不存在其他表的非主键信息。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">在开发过程中,并不一定要满足三大范式,有时候为了提高查询效率,可以在表中冗余其他表的字段。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;">2、DML 语句和 DDL 语句区别</h3> <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);"> DML 是数据库操作语言(Data Manipulation Language)的缩写,是指对数据库中表记录的操作,主要包括表记录的插入、更新、删除和查询,是开发人员日常使用最频繁的操作。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> DDL (Data Definition Language)是数据定义语言的缩写,简单来说,就是对数据库内部的对象进行创建、删除、修改的操作语言。它和 DML 语言的最大区别是 DML 只是对表内部数据的操作,而不涉及到表的定义、结构的修改,更不会涉及到其他对象。DDL 语句更多的被数据库管理员(DBA)所使用,一般的开发人员很少使用。 </section></li> </ul> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;">3、主键和外键的区别</h3> <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: black;">主键</strong>:用于唯一标识一行数据,不能有重复,不允许为空,且一个表只能有一个主键; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <strong style="color: black;">外键</strong>:用来和其他表建立联系,外键是另一表的主键,外键是可以有重复的,可以是空值。一个表可以有多个外键; </section></li> </ul> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;">4、drop、delete、truncate 区别</h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">(1)用法不同</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);"> <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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">drop</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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">drop table 表名</code> ,直接将表结构都删除掉,在删除表的时候使用。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">truncate</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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">truncate table 表名</code> ,只删除表中的数据,再插入数据的时候自增长 id 又从 1 开始,在清空表中数据的时候使用。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">delete</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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">delete from 表名 where 列名=值</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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">where</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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">truncate table 表名</code>作用类似。 </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">(2)属于不同的数据库语言</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);"> <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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">truncate</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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">drop</code> 属于 DDL(数据定义语言)语句,操作立即生效,原数据不放到 rollback segment 中,不能回滚,操作不触发 trigger。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">delete</code> 语句是 DML (数据库操作语言)语句,这个操作会放到 rollback segment 中,事务提交之后才生效。 </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">(3)执行速度不同</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);"> <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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">delete</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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">binlog</code>日志,而日志记录是需要消耗时间的,但是也有个好处方便数据回滚恢复。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">truncate</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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">delete</code>要快。除此之外,还会把表的自增值重置和索引恢复到初始大小等。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">drop</code>命令会把表占用的空间全部释放掉。 </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">一般来说:<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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">drop</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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">truncate</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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">delete</code></p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;">5、基础架构</h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">下图是 MySQL 的一个简要架构图,从下图你可以很清晰的看到客户端的一条 SQL 语句在 MySQL 内部是如何执行的。</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.7764530551415797" src="/upload/98899e8ed18d9c9e2cff50a3bc491e08.png" data-type="png" data-w="671" style="display: block;margin-right: auto;margin-left: auto;"> <figcaption style="margin-top: 5px;text-align: center;color: rgb(136, 136, 136);font-size: 14px;"> img </figcaption> </figure> <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: black;">连接器:</strong> 身份认证和权限相关(登录 MySQL 的时候)。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <strong style="color: black;">查询缓存:</strong> 执行查询语句的时候,会先查询缓存(MySQL 8.0 版本后移除,因为这个功能不太实用)。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <strong style="color: black;">分析器:</strong> 没有命中缓存的话,SQL 语句就会经过分析器,分析器说白了就是要先看你的 SQL 语句要干嘛,再检查你的 SQL 语句语法是否正确。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <strong style="color: black;">优化器:</strong> 按照 MySQL 认为最优的方案去执行。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <strong style="color: black;">执行器:</strong> 执行语句,然后从存储引擎返回数据。执行语句之前会先判断是否有权限,如果没有权限的话,就会报错。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <strong style="color: black;">插件式存储引擎</strong>:主要负责数据的存储和读取,采用的是插件式架构,支持 InnoDB、MyISAM、Memory 等多种存储引擎。 </section></li> </ul> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;">6、MyISAM 和 InnoDB 有什么区别?</h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">MySQL 5.5 之前,MyISAM 引擎是 MySQL 的默认存储引擎,MySQL 5.5 版本之后,InnoDB 是 MySQL 的默认存储引擎。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;"><strong>(1)是否支持行级锁</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">MyISAM 只有表级锁,而 InnoDB 支持行级锁和表级锁,默认为行级锁。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">具体的锁详情请参考阿Q的此篇文章:<a href="https://mp.weixin.qq.com/s?__biz=MzI5MDg2NjEzNA==&mid=2247484201&idx=1&sn=57f339e7126a815fbbbfc7398090f6be&scene=21#wechat_redirect" style="font-weight: bold;color: rgb(239, 112, 96);border-bottom: 1px solid rgb(239, 112, 96);" data-linktype="2">面试必备常见存储引擎与锁的分类,请查收</a></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;"><strong>(2)是否支持事务</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">MyISAM 不提供事务支持,InnoDB 提供事务支持,实现了 SQL 标准定义的四个隔离级别,具有提交和回滚事务的能力。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">InnoDB 默认使用的 REPEATABLE-READ(可重读)隔离级别是可以解决幻读问题发生的(基于 MVCC 和 Next-Key Lock)。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">关于 MySQL 事务以及解决幻读的详细介绍,可以看看阿Q写的这篇文章:<a href="https://mp.weixin.qq.com/s?__biz=MzI5MDg2NjEzNA==&mid=2247484182&idx=1&sn=09489278900940ff1ef90cd7c0c14f98&scene=21#wechat_redirect" style="font-weight: bold;color: rgb(239, 112, 96);border-bottom: 1px solid rgb(239, 112, 96);" data-linktype="2">InnoDB 解决幻读的方案--LBCC&MVCC</a></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;"><strong>(3)是否支持外键</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">MyISAM 不支持,而 InnoDB 支持。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;"><strong>(4)是否支持数据库异常崩溃后的安全恢复</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">MyISAM 不支持,而 InnoDB 支持。使用 InnoDB 的数据库在异常崩溃后,数据库重新启动的时候会保证数据库恢复到崩溃前的状态。这个恢复的过程依赖于 <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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">redo log</code> 。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;"><strong>(5)是否支持 MVCC</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">MyISAM 不支持,而 InnoDB 支持。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;"><strong>(6)索引实现</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">虽然 MyISAM 引擎和 InnoDB 引擎都是使用 B+Tree 作为索引结构,但是两者的实现方式不太一样。</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);"> InnoDB 引擎中,其数据文件本身就是索引文件。其表数据文件本身就是按 B+Tree 组织的一个索引结构,树的叶子节点 data 域保存了完整的数据记录。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> MyISAM 索引文件和数据文件是分离的,索引保存的是数据文件的指针。 </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;"><strong>(7)性能差别</strong></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">InnoDB 的性能比 MyISAM 更强大,不管是在读写混合模式下还是只读模式下,随着 CPU 核数的增加,InnoDB 的读写能力呈线性增长。MyISAM 因为读写不能并发,它的处理能力跟核数没关系。</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.33488372093023255" src="/upload/a71361b5b6b715915fafb5408605142e.png" data-type="png" data-w="1075" style="display: block;margin-right: auto;margin-left: auto;"> <figcaption style="margin-top: 5px;text-align: center;color: rgb(136, 136, 136);font-size: 14px;"> InnoDB 和 MyISAM 性能对比 </figcaption> </figure> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;">7、推荐自增id作为主键问题</h3> <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);"> 普通索引的 B+ 树上存放的是主键索引的值,如果该值较大,会 <strong style="color: black;">「导致普通索引的存储空间较大」</strong> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 使用自增 id 做主键索引新插入数据只要放在该页的最尾端就可以,直接 <strong style="color: black;">「按照顺序插入」</strong>,不用刻意维护 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 页分裂容易维护,当插入数据的当前页快满时,会发生页分裂的现象,如果主键索引不为自增 id,那么数据就可能从页的中间插入,页的数据会频繁的变动, <strong style="color: black;">「导致页分裂维护成本较高」</strong> </section></li> </ul> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;">8、为什么 MySQL 的自增主键不连续</h3> <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);"> 在MySQL 5.7及之前的版本,自增值保存在内存里,并没有持久化; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 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> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;">9、redo log 是做什么的?</h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;"><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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">redo log</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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">MySQL</code>拥有了崩溃恢复能力。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">比如 <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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">MySQL</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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">redo log</code>恢复数据,保证数据的持久性与完整性。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">更新表数据的时候,如果发现 <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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">Buffer Pool</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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">Buffer Pool</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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">redo log 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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">redo log</code> 文件里。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;">10、redo log 的刷盘时机</h3> <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.7197231833910035" src="/upload/937e4c7101d98be9d1791a297ef12a54.png" data-type="png" data-w="289" style="display: block;margin-right: auto;margin-left: auto;"> </figure> <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);"> 红色部分为 redo log buffer 属于内存 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 黄色部分为 page cache ,此时已经写入磁盘了,但是未进行持久化 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 绿色部分是硬盘,已经完成持久化 </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">InnoDB 存储引擎为 redo log 的刷盘策略提供了 innodb_flush_log_at_trx_commit 参数,它支持<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);"> 设置为0的时候,表示每次事务提交时 <strong style="color: black;">不进行刷盘</strong>操作,只是保留在 redo log buffer中,mysql 崩溃会丢失1s的数据; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 设置为1的时候,表示每次事务提交时 <strong style="color: black;">都将进行</strong>刷盘操作(默认值),持久化到磁盘; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 设置为2的时候,表示每次事务提交时都只把redo log buffer内容写入 <strong style="color: black;">page cache</strong>,OS宕机会丢失1s的数据,因为未进行持久化; </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">innodb_flush_log_at_trx_commit 参数默认为 1 ,也就是说当事务提交时会调用 fsync(同步操作) 对 redo log 进行刷盘。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">另外 InnoDB 存储引擎有一个后台<strong>线程</strong>,每隔1秒,就会把 redo log buffer 中的内容写到文件系统缓存(page cache),然后调用 fsync 刷盘。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">redo log buffer占用的空间即将达到 innodb_log_buffer_size 一半的时候,后台线程会主动刷盘。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;">11、redo log 是怎么记录日志的</h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">硬盘上存储的 <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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">redo log</code> 日志文件不只一个,而是以一个<strong>日志文件组</strong>的形式出现的,每个的<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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">redo</code>日志文件大小都是一样的。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">比如可以配置为一组<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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">4</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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">1GB</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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">redo log</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: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">4G</code>的内容。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">它采用的是环形数组形式,从头开始写,写到末尾又回到头循环写,如下图所示。</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img data-ratio="0.956973293768546" src="/upload/321f2bccf6504cc2509ff8a6db858478.png" data-type="png" data-w="674" style="display: block;margin-right: auto;margin-left: auto;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">所以,如果数据写满了但是还没有来得及将数据真正的刷入磁盘当中,那么就会发生<strong>「内存抖动」</strong>现象,从肉眼的角度来观察会发现 mysql 会宕机一会儿,此时就是正在刷盘了。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;">12、什么是 binlog</h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">binlog 是归档日志,属于 Server 层的日志,是一个二进制格式的文件,记录内容是语句的原始逻辑,类似于“给 ID=2 这一行的 c 字段加 1”。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">不管用什么存储引擎,只要发生了表数据更新,都会产生 <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: "Operator Mono", Cons
作者:微信小助手
<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="font-size: 16px;color: black;line-height: 1.6;word-spacing: 0px;letter-spacing: 0px;word-break: break-word;overflow-wrap: break-word;text-align: left;padding: 0.6px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;margin-bottom: 0px;" data-mpa-powered-by="yiban.io"> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;"><span style="letter-spacing: 0.1em;word-spacing: 0.2em;">我有一个朋友~</span></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">做了一个小破站,现在要实现一个站内信web消息推送的功能,对,就是下图这个小红点,一个很常用的功能。</p> <figure data-tool="mdnice编辑器" style="margin: 0;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.08426270136307311" src="/upload/db9252b5656016e5fb65125e9792c238.png" data-type="png" data-w="807" style="max-width: 100%;border-radius: 2px;display: block;margin: 20px auto;width: 85%;height: 100%;object-fit: contain;box-shadow: #84A1A8 0px 2px 5px;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">不过他还没想好用什么方式做,这里我帮他整理了一下几种方案,并简单做了实现。</p> <figure data-tool="mdnice编辑器" style="margin: 0;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.6847946725860156" src="/upload/4ca9741b96ca46d4001e832cca856f14.png" data-type="png" data-w="901" style="max-width: 100%;border-radius: 2px;display: block;margin: 20px auto;width: 85%;height: 100%;object-fit: contain;box-shadow: #84A1A8 0px 2px 5px;"> </figure> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;padding: 0px;font-weight: bold;font-size: 18px;color: #0e88eb;"><span style="display: none;"></span><span style="font-size: 18px;color: #0e88eb;">什么是消息推送(push)</span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">推送的场景比较多,比如有人关注我的公众号,这时我就会收到一条推送消息,以此来吸引我点击打开应用。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">消息推送(<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">push</code>)通常是指网站的运营工作等人员,通过某种工具对用户当前网页或移动设备APP进行的主动消息推送。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">消息推送一般又分为<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">web端消息推送</code>和<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">移动端消息推送</code>。</p> <figure data-tool="mdnice编辑器" style="margin: 0;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.3170940170940171" src="/upload/b8d5deebbbc4a634b79b343ea29615ec.png" data-type="png" data-w="1170" style="max-width: 100%;border-radius: 2px;display: block;margin: 20px auto;width: 85%;height: 100%;object-fit: contain;box-shadow: #84A1A8 0px 2px 5px;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">上边的这种属于移动端消息推送,web端消息推送常见的诸如站内信、未读邮件数量、监控报警数量等,应用的也非常广泛。</p> <figure data-tool="mdnice编辑器" style="margin: 0;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.2620320855614973" src="/upload/4d623c9f95c2aa1d9331288f3eddf9ba.png" data-type="png" data-w="1122" style="max-width: 100%;border-radius: 2px;display: block;margin: 20px auto;width: 85%;height: 100%;object-fit: contain;box-shadow: #84A1A8 0px 2px 5px;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">在具体实现之前,咱们再来分析一下前边的需求,其实功能很简单,只要触发某个事件(主动分享了资源或者后台主动推送消息),web页面的通知小红点就会实时的<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">+1</code>就可以了。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">通常在服务端会有若干张消息推送表,用来记录用户触发不同事件所推送不同类型的消息,前端主动查询(拉)或者被动接收(推)用户所有未读的消息数。</p> <figure data-tool="mdnice编辑器" style="margin: 0;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.42444444444444446" src="/upload/590ceaebf0c79ba8db4993de5e836110.png" data-type="png" data-w="1800" style="max-width: 100%;border-radius: 2px;display: block;margin: 20px auto;width: 85%;height: 100%;object-fit: contain;box-shadow: #84A1A8 0px 2px 5px;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">消息推送无非是推(<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">push</code>)和拉(<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">pull</code>)两种形式,下边我们逐个了解下。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;padding: 0px;font-weight: bold;font-size: 18px;color: #0e88eb;"><span style="display: none;"></span><span style="font-size: 18px;color: #0e88eb;">短轮询</span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">轮询(<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">polling</code>)应该是实现消息推送方案中最简单的一种,这里我们暂且将轮询分为<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">短轮询</code>和<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">长轮询</code>。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">短轮询很好理解,指定的时间间隔,由浏览器向服务器发出<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">HTTP</code>请求,服务器实时返回未读消息数据给客户端,浏览器再做渲染显示。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">一个简单的JS定时器就可以搞定,每秒钟请求一次未读消息数接口,返回的数据展示即可。</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("https://mmbiz.qpic.cn/mmbiz_svg/CJ35Z2cnZA3Dv8nvz8jxcibdLaD21YDUb5gJ8iaO0oBF9LI6rJ32Z56Vt5NibpXtgeAoBom9icpXdvBd9Jia74czxKXDusI0YXhcA/640?wx_fmt=svg") 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;">setInterval(() => {<br> // 方法请求<br> messageCount().<span style="color: #c678dd;line-height: 26px;">then</span>((res) => {<br> <span style="color: #c678dd;line-height: 26px;">if</span> (res.code === 200) {<br> this.messageCount = res.data<br> }<br> })<br>}, 1000);<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">效果还是可以的,短轮询实现固然简单,缺点也是显而易见,由于推送数据并不会频繁变更,无论后端此时是否有新的消息产生,客户端都会进行请求,势必会对服务端造成很大压力,浪费带宽和服务器资源。</p> <figure data-tool="mdnice编辑器" style="margin: 0;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.7565011820330969" src="/upload/b38f04a6daa322c6c4c947689374a091.png" data-type="gif" data-w="846" style="max-width: 100%;border-radius: 2px;display: block;margin: 20px auto;width: 85%;height: 100%;object-fit: contain;box-shadow: #84A1A8 0px 2px 5px;"> </figure> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;padding: 0px;font-weight: bold;font-size: 18px;color: #0e88eb;"><span style="display: none;"></span><span style="font-size: 18px;color: #0e88eb;">长轮询</span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">长轮询是对上边短轮询的一种改进版本,在尽可能减少对服务器资源浪费的同时,保证消息的相对实时性。长轮询在中间件中应用的很广泛,比如<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">Nacos</code>和<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">apollo</code>配置中心,消息队列<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">kafka</code>、<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">RocketMQ</code>中都有用到长轮询。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">这次我使用<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">apollo</code>配置中心实现长轮询的方式,应用了一个类<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">DeferredResult</code>,它是在<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">servelet3.0</code>后经过Spring封装提供的一种异步请求机制,直意就是延迟结果。</p> <figure data-tool="mdnice编辑器" style="margin: 0;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.5174193548387097" src="/upload/a9700f07d4379bbc95dd451252ee0835.png" data-type="png" data-w="1550" style="max-width: 100%;border-radius: 2px;display: block;margin: 20px auto;width: 85%;height: 100%;object-fit: contain;box-shadow: #84A1A8 0px 2px 5px;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;"><code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">DeferredResult</code>可以允许容器线程快速释放占用的资源,不阻塞请求线程,以此接受更多的请求提升系统的吞吐量,然后启动异步工作线程处理真正的业务逻辑,处理完成调用<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">DeferredResult.setResult(200)</code>提交响应结果。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">下边我们用长轮询来实现消息推送。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">因为一个ID可能会被多个长轮询请求监听,所以我采用了<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">guava</code>包提供的<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">Multimap</code>结构存放长轮询,一个key可以对应多个value。一旦监听到key发生变化,对应的所有长轮询都会响应。前端得到非请求超时的状态码,知晓数据变更,主动查询未读消息数接口,更新页面数据。</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("https://mmbiz.qpic.cn/mmbiz_svg/CJ35Z2cnZA3Dv8nvz8jxcibdLaD21YDUb5gJ8iaO0oBF9LI6rJ32Z56Vt5NibpXtgeAoBom9icpXdvBd9Jia74czxKXDusI0YXhcA/640?wx_fmt=svg") 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;">@Controller</span><br><span style="color: #61aeee;line-height: 26px;">@RequestMapping</span>(<span style="color: #98c379;line-height: 26px;">"/polling"</span>)<br><span style="color: #c678dd;line-height: 26px;">public</span> <span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;">class</span> <span style="color: #e6c07b;line-height: 26px;">PollingController</span> </span>{<br><br> <span style="color: #5c6370;font-style: italic;line-height: 26px;">// 存放监听某个Id的长轮询集合</span><br> <span style="color: #5c6370;font-style: italic;line-height: 26px;">// 线程同步结构</span><br> <span style="color: #c678dd;line-height: 26px;">public</span> <span style="color: #c678dd;line-height: 26px;">static</span> Multimap<String, DeferredResult<String>> watchRequests = Multimaps.synchronizedMultimap(HashMultimap.create());<br><br> <span style="color: #5c6370;font-style: italic;line-height: 26px;">/**<br> * 公众号:程序员小富<br> * 设置监听<br> */</span><br> <span style="color: #61aeee;line-height: 26px;">@GetMapping</span>(path = <span style="color: #98c379;line-height: 26px;">"watch/{id}"</span>)<br> <span style="color: #61aeee;line-height: 26px;">@ResponseBody</span><br> <span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;">public</span> DeferredResult<String> <span style="color: #61aeee;line-height: 26px;">watch</span><span style="line-height: 26px;">(@PathVariable String id)</span> </span>{<br> <span style="color: #5c6370;font-style: italic;line-height: 26px;">// 延迟对象设置超时时间</span><br> DeferredResult<String> deferredResult = <span style="color: #c678dd;line-height: 26px;">new</span> DeferredResult<>(TIME_OUT);<br> <span style="color: #5c6370;font-style: italic;line-height: 26px;">// 异步请求完成时移除 key,防止内存溢出</span><br> deferredResult.onCompletion(() -> {<br> watchRequests.remove(id, deferredResult);<br> });<br> <span style="color: #5c6370;font-style: italic;line-height: 26px;">// 注册长轮询请求</span><br> watchRequests.put(id, deferredResult);<br> <span style="color: #c678dd;line-height: 26px;">return</span> deferredResult;<br> }<br><br> <span style="color: #5c6370;font-style: italic;line-height: 26px;">/**<br> * 公众号:程序员小富<br> * 变更数据<br> */</span><br> <span style="color: #61aeee;line-height: 26px;">@GetMapping</span>(path = <span style="color: #98c379;line-height: 26px;">"publish/{id}"</span>)<br> <span style="color: #61aeee;line-height: 26px;">@ResponseBody</span><br> <span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;">public</span> String <span style="color: #61aeee;line-height: 26px;">publish</span><span style="line-height: 26px;">(@PathVariable String id)</span> </span>{<br> <span style="color: #5c6370;font-style: italic;line-height: 26px;">// 数据变更 取出监听ID的所有长轮询请求,并一一响应处理</span><br> <span style="color: #c678dd;line-height: 26px;">if</span> (watchRequests.containsKey(id)) {<br> Collection<DeferredResult<String>> deferredResults = watchRequests.get(id);<br> <span style="color: #c678dd;line-height: 26px;">for</span> (DeferredResult<String> deferredResult : deferredResults) {<br> deferredResult.setResult(<span style="color: #98c379;line-height: 26px;">"我更新了"</span> + <span style="color: #c678dd;line-height: 26px;">new</span> Date());<br> }<br> }<br> <span style="color: #c678dd;line-height: 26px;">return</span> <span style="color: #98c379;line-height: 26px;">"success"</span>;<br> }<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">当请求超过设置的超时时间,会抛出<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">AsyncRequestTimeoutException</code>异常,这里直接用<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">@ControllerAdvice</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("https://mmbiz.qpic.cn/mmbiz_svg/CJ35Z2cnZA3Dv8nvz8jxcibdLaD21YDUb5gJ8iaO0oBF9LI6rJ32Z56Vt5NibpXtgeAoBom9icpXdvBd9Jia74czxKXDusI0YXhcA/640?wx_fmt=svg") 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;">@ControllerAdvice<br>public class AsyncRequestTimeoutHandler {<br><br> @ResponseStatus(HttpStatus.NOT_MODIFIED)<br> @ResponseBody<br> @ExceptionHandler(AsyncRequestTimeoutException.class)<br> public String asyncRequestTimeoutHandler(AsyncRequestTimeoutException e) {<br> System.out.println(<span style="color: #98c379;line-height: 26px;">"异步请求超时"</span>);<br> <span style="color: #e6c07b;line-height: 26px;">return</span> <span style="color: #98c379;line-height: 26px;">"304"</span>;<br> }<br>}<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">我们来测试一下,首先页面发起长轮询请求<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">/polling/watch/10086</code>监听消息更变,请求被挂起,不变更数据直至超时,再次发起了长轮询请求;紧接着手动变更数据<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">/polling/publish/10086</code>,长轮询得到响应,前端处理业务逻辑完成后再次发起请求,如此循环往复。</p> <figure data-tool="mdnice编辑器" style="margin: 0;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.5844255975327679" src="/upload/84b2a55563a5cd3aee77212095443993.png" data-type="gif" data-w="1297" style="max-width: 100%;border-radius: 2px;display: block;margin: 20px auto;width: 85%;height: 100%;object-fit: contain;box-shadow: #84A1A8 0px 2px 5px;"> </figure> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">长轮询相比于短轮询在性能上提升了很多,但依然会产生较多的请求,这是它的一点不完美的地方。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;padding: 0px;font-weight: bold;font-size: 18px;color: #0e88eb;"><span style="display: none;"></span><span style="font-size: 18px;color: #0e88eb;">iframe流</span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;color: black;margin: 10px 1px;line-height: 1.75;letter-spacing: 0.10em;font-size: 16px;word-spacing: 0.2em;">iframe流就是在页面中插入一个隐藏的<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;"><iframe></code>标签,通过在<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">src</code>中请求消息数量API接口,由此在服务端和客户端之间创建一条长连接,服务端持续向<code style="font-size: 14px;word-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin: 0 2px;color: #1e6bb8;background-color: rgba(27,31,35,.05);font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;word-break: break-all;">iframe</code>传输数据。</p> <blockquote data-tool="mdnice编辑器" style="border-width: initial;border-style: none;border-color: initial;display: block;font-size: 0.9em;overflow: auto;margin-bottom: 20px;margin-top: 20px;font-style: normal;padding: 10px;line-height: 1.8;border-radius: 0px 0px 10px 10px;color: rgb(14, 136, 235);background: rgb(255, 255, 255);box-shadow: rgb(132, 161, 168) 0px 10px 15px;"> <span style="display: inline;color: #0e88eb;font-size: 4em;font-family: Arial,serif;line-height: 1em;font-weight: 700;">“</span> <p style="padding-top: 8px;padding-bottom: 8px;
作者:微信小助手
<h2 data-tool="mdnice编辑器" style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;margin-top: 24px;"><span style="font-size: 20px;"><strong style="outline: 0px;visibility: visible;"><span style="outline: 0px;font-family: arial, helvetica, sans-serif;visibility: visible;">背景</span></strong></span></h2> <p style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);visibility: visible;"><strong style="outline: 0px;visibility: visible;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;visibility: visible;"><br style="outline: 0px;visibility: visible;"></span></strong></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;visibility: visible;">「使用线程池 ThreadPoolExecutor 过程中你是否有以下痛点呢?」</span></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;visibility: visible;"><br style="outline: 0px;visibility: visible;"></span></p> <blockquote data-tool="mdnice编辑器" style="outline: 0px;color: var(--weui-FG-1);font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);visibility: visible;"> <p style="outline: 0px;text-align: left;visibility: visible;"><span style="outline: 0px;font-size: 14px;font-family: arial, helvetica, sans-serif;visibility: visible;">1.代码中创建了一个 ThreadPoolExecutor,但是不知道那几个核心参数设置多少比较合适</span></p> <p style="outline: 0px;text-align: left;visibility: visible;"><span style="outline: 0px;font-family: arial, helvetica, sans-serif;font-size: 14px;visibility: visible;">2.凭经验设置参数值,上线后发现需要调整,改代码重启服务,非常麻烦</span></p> <p style="outline: 0px;text-align: left;visibility: visible;"><span style="outline: 0px;font-family: arial, helvetica, sans-serif;font-size: 14px;visibility: visible;">3.线程池相对开发人员来说是个黑盒,运行情况不能及时感知到,直到出现问题</span></p> </blockquote> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;visibility: visible;"><br style="outline: 0px;visibility: visible;"></span></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;visibility: visible;">如果你有以上痛点,动态可监控线程池(DynamicTp)或许能帮助到你。</span></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;visibility: visible;"><br style="outline: 0px;visibility: visible;"></span></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;visibility: visible;">如果看过 ThreadPoolExecutor 的源码,大概可以知道它对核心参数基本都有提供 set / get 方法以及一些扩展方法,可以在运行时动态修改、获取相应的值。</span></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;visibility: visible;"><br style="outline: 0px;visibility: visible;"></span></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;visibility: visible;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;visibility: visible;">现在大多数的互联网项目其实都会微服务化部署,有一套自己的服务治理体系,微服务组件中的分布式配置中心扮演的就是动态修改配置, 实时生效的角色。那么我们是否可以结合配置中心来做运行时线程池参数的动态调整呢?答案是肯定的,而且配置中心相对都是高可用的, 使用它也不用过于担心配置推送出现问题这类事儿,而且也能减少研发动态线程池组件的难度和工作量。</span></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;">「综上,可以总结出以下的背景」</span></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span></p> <ul data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 1.5em;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"> <section style="outline: 0px;text-align: left;"> <span style="outline: 0px;">「广泛性」:在 Java 开发中,想要提高系统性能,线程池已经是一个 90%以上的人都会选择使用的基础工具</span> </section></li> </ul> <section style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"> <br style="outline: 0px;"> </section> <ul data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 1.5em;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"> <section style="outline: 0px;text-align: left;"> <span style="outline: 0px;">「不确定性」:项目中可能会创建很多线程池,既有 IO 密集型的,也有 CPU 密集型的,但线程池的参数并不好确定;需要有套机制在运行过程中动态去调整参数</span> </section></li> </ul> <section style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"> <br style="outline: 0px;"> </section> <ul data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 1.5em;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"> <section style="outline: 0px;text-align: left;"> <span style="outline: 0px;">「无感知性」:线程池运行过程中的各项指标一般感知不到;需要有套监控报警机制在事前、事中就能让开发人员感知到线程池的运行状况,及时处理</span> </section></li> </ul> <section style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"> <br style="outline: 0px;"> </section> <ul data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 1.5em;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><p style="outline: 0px;text-align: left;margin-bottom: 24px;"><span style="outline: 0px;">「高可用性」:配置变更需要及时推送到客户端;需要有高可用的配置管理推送服务,配置中心是现在大多数互联网系统都会使用的组件,与之结合可以大幅度减少开发量及接入难度</span></p></li> </ul> <h2 data-tool="mdnice编辑器" style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="font-size: 20px;"><strong style="outline: 0px;"><span style="outline: 0px;font-family: arial, helvetica, sans-serif;">简介</span></strong></span></h2> <p style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"><strong style="outline: 0px;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span></strong></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;">「基于以上背景分析,我们对线程池 ThreadPoolExecutor 做一些扩展增强,主要实现以下目标」</span></p> <blockquote data-tool="mdnice编辑器" style="outline: 0px;color: var(--weui-FG-1);font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <p style="outline: 0px;text-align: left;"><span style="outline: 0px;font-family: arial, helvetica, sans-serif;">❝1.实现对运行中线程池参数的动态修改,实时生效</span></p> <p style="outline: 0px;text-align: left;"><span style="outline: 0px;font-family: arial, helvetica, sans-serif;">2.实时监控线程池的运行状态,触发设置的报警策略时报警,报警信息推送办公平台</span></p> <p style="outline: 0px;text-align: left;"><span style="outline: 0px;font-family: arial, helvetica, sans-serif;">3.定时采集线程池指标数据,配合像 grafana 这种可视化监控平台做大盘监控❞</span></p> </blockquote> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;">「经过多个版本的迭代,目前最新版本 v1.0.9 具有以下特性」 ✅</span></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span></p> <ul data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 1.5em;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"> <section style="outline: 0px;text-align: left;"> <span style="outline: 0px;">「代码零侵入」:所有配置都放在配置中心,对业务代码零侵入</span> </section></li> </ul> <section style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"> <br style="outline: 0px;"> </section> <ul data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 1.5em;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><p style="outline: 0px;text-align: left;margin-bottom: 0px;line-height: 1.75em;margin-top: 0px;"><span style="outline: 0px;">「轻量简单」:基于 SpringBoot 实现,引入 starter,接入只需简单 4 步就可完成,顺利 3 分钟搞定</span></p></li> </ul> <p style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;margin-bottom: 0px;line-height: 1.75em;margin-top: 0px;"><br></p> <ul data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 1.5em;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><p style="outline: 0px;text-align: left;margin-bottom: 0px;line-height: 1.75em;margin-top: 0px;"><span style="outline: 0px;">「高可扩展」:框架核心功能都提供 SPI 接口供用户自定义个性化实现(配置中心、配置文件解析、通知告警、监控数据采集、任务包装等等)</span></p></li> </ul> <p style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;margin-bottom: 0px;line-height: 1.75em;margin-top: 0px;"><br></p> <ul data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 1.5em;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><p style="outline: 0px;text-align: left;margin-bottom: 0px;line-height: 1.75em;margin-top: 0px;"><span style="outline: 0px;">「线上大规模应用」:参考美团线程池实践,美团内部已经有该理论成熟的应用经验</span></p></li> </ul> <p style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;margin-bottom: 0px;line-height: 1.75em;margin-top: 0px;"><br></p> <ul data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 1.5em;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><p style="outline: 0px;text-align: left;margin-bottom: 0px;line-height: 1.75em;margin-top: 0px;"><span style="outline: 0px;">「多平台通知报警」:提供多种报警维度(配置变更通知、活性报警、容量阈值报警、拒绝触发报警、任务执行或等待超时报警),已支持企业微信、钉钉、飞书、邮件报警,同时提供 SPI 接口可自定义扩展实现</span></p></li> </ul> <p style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;margin-bottom: 0px;line-height: 1.75em;margin-top: 0px;"><br></p> <ul data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 1.5em;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><p style="outline: 0px;text-align: left;margin-bottom: 0px;line-height: 1.75em;margin-top: 0px;"><span style="outline: 0px;">「监控」:定时采集线程池指标数据,支持通过 MicroMeter、JsonLog 日志输出、Endpoint 三种方式,可通过 SPI 接口自定义扩展实现</span></p></li> </ul> <section style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"> <br style="outline: 0px;"> </section> <ul data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 1.5em;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"> <section style="outline: 0px;text-align: left;"> <span style="outline: 0px;">「任务增强」:提供任务包装功能,实现 TaskWrapper 接口即可,如 MdcTaskWrapper、TtlTaskWrapper、SwTraceTaskWrapper,可以支持线程池上下文信息传递</span> </section></li> </ul> <section style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"> <br style="outline: 0px;"> </section> <ul data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 1.5em;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"> <section style="outline: 0px;text-align: left;"> <span style="outline: 0px;">「兼容性」:JUC 普通线程池和 Spring 中的 ThreadPoolTaskExecutor 也可以被框架监控,@Bean定义时加 @DynamicTp 注解即可</span> </section></li> </ul> <section style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"> <br style="outline: 0px;"> </section> <ul data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 1.5em;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"> <section style="outline: 0px;text-align: left;"> <span style="outline: 0px;">「可靠性」:框架提供的线程池实现 Spring 生命周期方法,可以在 Spring 容器关闭前尽可能多的处理队列中的任务</span> </section></li> </ul> <section style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"> <br style="outline: 0px;"> </section> <ul data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 1.5em;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"> <section style="outline: 0px;text-align: left;"> <span style="outline: 0px;">「多模式」:参考 Tomcat 线程池提供了 IO 密集型场景使用的 EagerDtpExecutor 线程池</span> </section></li> </ul> <section style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"> <br style="outline: 0px;"> </section> <ul data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 1.5em;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"> <section style="outline: 0px;text-align: left;"> <span style="outline: 0px;">「支持多配置中心」:基于主流配置中心实现线程池参数动态调整,实时生效,已支持 Nacos、Apollo、Zookeeper、Consul、Etcd,同时也提供 SPI 接口可自定义扩展实现</span> </section></li> </ul> <section style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"> <br style="outline: 0px;"> </section> <ul data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 1.5em;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"> <section style="outline: 0px;text-align: left;"> <span style="outline: 0px;">「中间件线程池管理」:集成管理常用第三方组件的线程池,已集成Tomcat、Jetty、Undertow、Dubbo、RocketMq、Hystrix、Grpc 等组件的线程池管理(调参、监控报警)</span> </section></li> </ul> <h2 data-tool="mdnice编辑器" style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span></h2> <h2 data-tool="mdnice编辑器" style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;margin-top: 24px;"><span style="font-size: 20px;"><strong style="outline: 0px;"><span style="outline: 0px;font-family: arial, helvetica, sans-serif;">架构设计</span></strong></span></h2> <p style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"><strong style="outline: 0px;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span></strong></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;">框架功能大体可以分为以下几个模块</span></p> <blockquote data-tool="mdnice编辑器" style="outline: 0px;color: var(--weui-FG-1);font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <p style="outline: 0px;text-align: left;"><span style="outline: 0px;font-family: arial, helvetica, sans-serif;">1.配置变更监听模块</span></p> <p style="outline: 0px;text-align: left;"><span style="outline: 0px;font-family: arial, helvetica, sans-serif;">2.服务内部线程池管理模块 </span></p> <p style="outline: 0px;text-align: left;"><span style="outline: 0px;font-family: arial, helvetica, sans-serif;">3.三方组件线程池管理模块</span></p> <p style="outline: 0px;text-align: left;"><span style="outline: 0px;font-family: arial, helvetica, sans-serif;">4.监控模块 </span></p> <p style="outline: 0px;text-align: left;"><span style="outline: 0px;font-family: arial, helvetica, sans-serif;">5.通知告警模块</span></p> </blockquote> <h4 data-tool="mdnice编辑器" style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"></h4> <h4 data-tool="mdnice编辑器" style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;margin-top: 32px;"><span style="font-size: 20px;"><strong style="outline: 0px;"><span style="outline: 0px;font-family: arial, helvetica, sans-serif;">代码结构</span></strong></span></h4> <p style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"><strong style="outline: 0px;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span></strong></p> <figure data-tool="mdnice编辑器" style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <img class="rich_pages wxw-img" data-ratio="1.5472186287192755" src="/upload/bc09b0b95257aebccb8841ddfbb596d4.png" data-w="773" style="outline: 0px;width: 677px !important;visibility: visible !important;"> <figcaption style="outline: 0px;text-align: left;"> <br style="outline: 0px;"> </figcaption> </figure> <blockquote data-tool="mdnice编辑器" style="outline: 0px;color: var(--weui-FG-1);font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <ol class="list-paddingleft-1" style="padding-left: 1.5em;outline: 0px;"> <li style="outline: 0px;font-family: arial, helvetica, sans-serif;"> <section style="outline: 0px;text-align: left;"> <span style="outline: 0px;">「adapter 模块」:主要是适配一些第三方组件的线程池管理,目前已经实现的有 SpringBoot 内置的三大 web 容器(Tomcat、Jetty、Undertow)、Dubbo、RocketMq、Hystrix、Grpc 的线程池管理, 后续会接入其他常用组件的线程池管理。</span> </section></li> <li style="outline: 0px;font-family: arial, helvetica, sans-serif;"> <section style="outline: 0px;text-align: left;"> <span style="outline: 0px;">「common 模块」:主要是一些各个模板都会用到的类,解耦依赖,复用代码,大家日常开发中可能也经常会这样做。</span> </section></li> <li style="outline: 0px;font-family: arial, helvetica, sans-serif;"> <section style="outline: 0px;text-align: left;"> <span style="outline: 0px;">「core 模块」:该框架的核心代码都在这个模块里,包括动态调整参数,监控报警,以及串联整个项目流程都在此。</span> </section></li> <li style="outline: 0px;font-family: arial, helvetica, sans-serif;"> <section style="outline: 0px;text-align: left;"> <span style="outline: 0px;">「example 模块」:提供一个简单使用示例,方便使用者参照</span> </section></li> <li style="outline: 0px;font-family: arial, helvetica, sans-serif;"> <section style="outline: 0px;text-align: left;"> <span style="outline: 0px;">「extension 模块」:放一些扩展功能实现,比如基于 redis 的流控扩展、邮件发送扩展、skywalking 上下文传递扩展等</span> </section></li> <li style="outline: 0px;font-family: arial, helvetica, sans-serif;"> <section style="outline: 0px;text-align: left;"> <span style="outline: 0px;">「logging 模块」:用于配置框架内部日志的输出,目前主要用于输出线程池监控指标数据到指定文件</span> </section></li> <li style="outline: 0px;font-family: arial, helvetica, sans-serif;"> <section style="outline: 0px;text-align: left;"> <span style="outline: 0px;">「starter模块」:提供独立功能模块的依赖封装、自动配置等相关。</span> </section></li> </ol> </blockquote> <h4 data-tool="mdnice编辑器" style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span></h4> <h4 data-tool="mdnice编辑器" style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;margin-top: 16px;"><span style="font-size: 20px;"><strong style="outline: 0px;"><span style="outline: 0px;font-family: arial, helvetica, sans-serif;">配置变更监听模块</span></strong></span></h4> <section style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);line-height: 1.75em;"> <span style="letter-spacing: 1px;"><strong style="outline: 0px;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span></strong></span> </section> <section style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;line-height: 1.75em;"> <span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;letter-spacing: 1px;">1.监听特定配置中心的指定配置文件(已实现 Nacos、Apollo、Zookeeper、Consul、Etcd),可通过内部提供的SPI接口扩展其他实现</span> </section> <section style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;line-height: 1.75em;"> <span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;letter-spacing: 1px;"><br style="outline: 0px;"></span> </section> <section style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;line-height: 1.75em;"> <span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;letter-spacing: 1px;">2.解析配置文件内容,内置实现 yml、properties、json 配置文件的解析,可通过内部提供的 SPI 接口扩展其他实现</span> </section> <section style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;line-height: 1.75em;"> <span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;letter-spacing: 1px;"><br style="outline: 0px;"></span> </section> <section style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;line-height: 1.75em;"> <span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;letter-spacing: 1px;">3.通知线程池管理模块实现参数的刷新</span> </section> <section style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;margin-top: 8px;"> <span style="outline: 0px;font-family: arial, helvetica, sans-serif;font-size: 20px;"><br style="outline: 0px;"></span> </section> <h4 data-tool="mdnice编辑器" style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;margin-top: 8px;"><span style="font-size: 20px;"><strong style="outline: 0px;"><span style="outline: 0px;font-family: arial, helvetica, sans-serif;">服务内部线程池管理模块</span></strong></span></h4> <p style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"><strong style="outline: 0px;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span></strong></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;">1.服务启动时从配置中心拉取配置,生成线程池实例注册到内部线程池注册中心以及 Spring 容器中</span></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;">2.接受配置监听模块的刷新事件,实现线程池参数的刷新</span></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;">3.代码中通过依赖注入(推荐)或者 DtpRegistry.getDtpExecutor() 方法根据线程池名称来获取线程池实例</span></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span></p> <h4 data-tool="mdnice编辑器" style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;margin-top: 16px;"><span style="font-size: 20px;"><strong style="outline: 0px;"><span style="font-size: 20px;outline: 0px;font-family: arial, helvetica, sans-serif;">三方组件线程池管理</span></strong></span></h4> <p style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"><strong style="outline: 0px;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span></strong></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;">1.服务启动获取第三方中间件的线程池,被框架管理起来</span></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;">2.接受参数刷新、指标收集、通知报警事件,进行相应的处理</span></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span></p> <h4 data-tool="mdnice编辑器" style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;margin-top: 16px;"><span style="font-size: 20px;"><strong style="outline: 0px;"><span style="font-size: 20px;outline: 0px;font-family: arial, helvetica, sans-serif;">监控模块</span></strong></span></h4> <p style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"><strong style="outline: 0px;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span></strong></p> <section style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;margin-bottom: 16px;"> <span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;">实现监控指标采集以及输出,默认提供以下三种方式,也可通过内部提供的 SPI 接口扩展其他实现</span> </section> <ol data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 1.5em;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><p style="outline: 0px;text-align: left;line-height: 1.75em;margin-bottom: 16px;"><span style="outline: 0px;">默认实现 JsonLog 输出到磁盘,可以自己采集解析日志,存储展示</span></p></li> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><p style="outline: 0px;text-align: left;line-height: 1.75em;margin-bottom: 16px;"><span style="outline: 0px;">MicroMeter采集,引入 MicroMeter 相关依赖,暴露相关端点,采集指标数据,结合 Grafana 做监控大盘</span></p></li> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><p style="outline: 0px;text-align: left;line-height: 1.75em;margin-bottom: 16px;"><span style="outline: 0px;">暴雷自定义 Endpoint 端点(dynamic-tp),可通过 http 方式实时访问</span></p></li> </ol> <h4 data-tool="mdnice编辑器" style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><br style="outline: 0px;"></h4> <h4 data-tool="mdnice编辑器" style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="font-size: 20px;"><strong style="outline: 0px;"><span style="font-size: 20px;outline: 0px;font-family: arial, helvetica, sans-serif;">通知告警模块</span></strong></span></h4> <p style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"><strong style="outline: 0px;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span></strong></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;">对接办公平台,实现通知告警功能,已支持钉钉、企微、飞书、邮件,可通过内部提供的 SPI 接口扩展其他实现,通知告警类型如下:</span></p> <p data-tool="mdnice编辑器" style="margin-bottom: 0px;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;"><span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span></p> <ol data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 1.5em;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;letter-spacing: 1px;"> <section style="outline: 0px;text-align: left;line-height: 1.75em;margin-bottom: 8px;"> <span style="outline: 0px;letter-spacing: 1px;">线程池主要参数变更通知</span> </section></li> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;letter-spacing: 1px;"> <section style="outline: 0px;text-align: left;line-height: 1.75em;margin-bottom: 8px;"> <span style="outline: 0px;letter-spacing: 1px;">阻塞队列容量达到设置的告警阈值</span> </section></li> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;letter-spacing: 1px;"> <section style="outline: 0px;text-align: left;line-height: 1.75em;margin-bottom: 8px;"> <span style="outline: 0px;letter-spacing: 1px;">线程池活性达到设置的告警阈值</span> </section></li> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;letter-spacing: 1px;"> <section style="outline: 0px;text-align: left;line-height: 1.75em;margin-bottom: 8px;"> <span style="outline: 0px;letter-spacing: 1px;">触发拒绝策略告警,格式:A/B,A:该报警项前后两次报警区间累加数量,B:该报警项累计总数</span> </section></li> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;letter-spacing: 1px;"> <section style="outline: 0px;text-align: left;line-height: 1.75em;margin-bottom: 8px;"> <span style="outline: 0px;letter-spacing: 1px;">任务执行超时告警,格式:A/B,A:该报警项前后两次报警区间累加数量,B:该报警项累计总数</span> </section></li> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;letter-spacing: 1px;"> <section style="outline: 0px;text-align: left;line-height: 1.75em;margin-bottom: 8px;"> <span style="outline: 0px;letter-spacing: 1px;">任务等待超时告警,格式:A/B,A:该报警项前后两次报警区间累加数量,B:该报警项累计总数</span> <span style="outline: 0px;"></span> </section></li> </ol> <figure data-tool="mdnice编辑器" style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <img class="rich_pages wxw-img" data-ratio="0.6953703703703704" src="/upload/b1db3ebb48d6023d90c65286e5dee3c0.png" data-w="1080" style="margin: 20px auto;outline: 0px;border-radius: 0px 0px 5px 5px;display: block;object-fit: contain;box-shadow: rgb(132, 161, 168) 0px 10px 15px;visibility: visible !important;width: 488.75px !important;"> <figcaption style="outline: 0px;text-align: left;"> <span style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><br style="outline: 0px;"></span> </figcaption> </figure> <h2 data-tool="mdnice编辑器" style="outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);text-align: left;margin-top: 16px;margin-bottom: 8px;"><span style="font-size: 20px;"><strong style="outline: 0px;"><span style="font-size: 20px;outline: 0px;font-family: arial, helvetica, sans-serif;">项目地址</span></strong></span></h2> <ul data-tool="mdnice编辑器" class="list-paddingleft-1" style="padding-left: 1.5em;outline: 0px;font-family: system-ui, -apple-system, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-wrap: wrap;background-color: rgb(255, 255, 255);"> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"><p style="outline: 0px;text-align: left;margin-top: 0px;"><span style="outline: 0px;">gitee地址:https://gitee.com/dromara/dynamic-tp</span></p></li> <li style="outline: 0px;font-size: 16px;font-family: arial, helvetica, sans-serif;"> <section style="outline: 0px;text-align: left;"> <span style="outline: 0px;">github地址:https://github.com/dromara/dynamic-tp</span> </section></li> </ul>
作者:微信小助手
<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;counter-reset: counterh1 0 counterh2 0 counterh3 0;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;" data-mpa-powered-by="yiban.io"> <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);"> <a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzI4Njc5NjM1NQ==&mid=2247520667&idx=2&sn=7c4f33093c46e9d07d4afd1dfba7542f&chksm=ebd5aeb7dca227a16bf221f9cbaa464676988ef468b8e7e315234a0681c58bffb5600d6c9dad&scene=21#wechat_redirect" textvalue="什么是分布式kafka介绍消息的顺序消费如何保证消息的顺序消费" linktype="text" imgurl="" imgdata="null" data-itemshowtype="0" tab="innerlink" data-linktype="2">什么是分布式</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzI4Njc5NjM1NQ==&mid=2247520667&idx=2&sn=7c4f33093c46e9d07d4afd1dfba7542f&chksm=ebd5aeb7dca227a16bf221f9cbaa464676988ef468b8e7e315234a0681c58bffb5600d6c9dad&scene=21#wechat_redirect" textvalue="什么是分布式kafka介绍消息的顺序消费如何保证消息的顺序消费" linktype="text" imgurl="" imgdata="null" data-itemshowtype="0" tab="innerlink" data-linktype="2">kafka介绍</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzI4Njc5NjM1NQ==&mid=2247520667&idx=2&sn=7c4f33093c46e9d07d4afd1dfba7542f&chksm=ebd5aeb7dca227a16bf221f9cbaa464676988ef468b8e7e315234a0681c58bffb5600d6c9dad&scene=21#wechat_redirect" textvalue="什么是分布式kafka介绍消息的顺序消费如何保证消息的顺序消费" linktype="text" imgurl="" imgdata="null" data-itemshowtype="0" tab="innerlink" data-linktype="2">消息的顺序消费</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzI4Njc5NjM1NQ==&mid=2247520667&idx=2&sn=7c4f33093c46e9d07d4afd1dfba7542f&chksm=ebd5aeb7dca227a16bf221f9cbaa464676988ef468b8e7e315234a0681c58bffb5600d6c9dad&scene=21#wechat_redirect" textvalue="什么是分布式kafka介绍消息的顺序消费如何保证消息的顺序消费" linktype="text" imgurl="" imgdata="null" data-itemshowtype="0" tab="innerlink" data-linktype="2">如何保证消息的顺序消费</a> </section></li> </ul> <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.5706106870229007" src="/upload/4d8ed236faa99750685dcca66137c28c.png" data-type="png" data-w="1048" style="display: block;margin-right: auto;margin-left: auto;"> </figure> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 22px;"><span style="display: inline-block;"><span style="counter-increment: counterh2;color: rgb(159,205,208);border-bottom: 4px solid rgb(159,205,208);font-size: 18px;padding: 2px 4px;">1</span></span><span style="font-size: 18px;border-bottom: 4px solid rgb(37,132,181);padding: 2px 4px;color: rgb(37,132,181);">什么是分布式</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">分布式是指将计算任务分散到多个计算节点上进行并行处理的一种计算模型。在分布式系统中,多台计算机通过网络互联,共同协作完成任务。每个计算节点都可以独立运行,并且可以相互通和协调。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">这种分布式的架构可以提高计算能力和可靠性,充分利用集群资源,提高系统的扩展性和灵活性。常见的分布式系统包括分布式数据库、分布式文件系统、分布式计算等。分布式系统用于处理大规模的数据和复杂的计算任务,适用于各种领域,如互联网、云计算、大数据分析等。</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.6564814814814814" src="/upload/278db3b1f820192f5ff3b29a6c57477d.png" data-type="png" data-w="1080" style="display: block;margin-right: auto;margin-left: auto;"> </figure> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 22px;"><span style="display: inline-block;"><span style="counter-increment: counterh2;color: rgb(159,205,208);border-bottom: 4px solid rgb(159,205,208);font-size: 18px;padding: 2px 4px;">2</span></span><span style="font-size: 18px;border-bottom: 4px solid rgb(37,132,181);padding: 2px 4px;color: rgb(37,132,181);">kafka介绍</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">Kafka是一种高性能、分布式的流式数据平台,由Apache基金会开发和维护。它的设计目标是实时、可持久地处理大规模的流式数据。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">Kafka的核心概念是一个分布式的发布-订阅消息系统。它以可扩展性和持久性为重点,通过将数据分割成多个分区并存储在多个服务器上来实现高吞吐量和故障容忍性。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">Kafka的架构主要由以下几个关键组件组成:</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);"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;"><strong style="color: rgb(37, 132, 181);">Producer(生产者)</strong>:负责向Kafka的Topic(主题)发布消息。生产者可以将消息发送到指定的Topic,并指定消息的键(key),Kafka将根据键将消息路由到对应的分区。</p> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;"><strong style="color: rgb(37, 132, 181);">Consumer(消费者)</strong>:消费者可以订阅一个或多个Topic,并从分区中消费消息。Kafka允许多个消费者组(consumer group)共同消费一个Topic中的消息,实现高吞吐量和负载均衡。</p> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;"><strong style="color: rgb(37, 132, 181);">Broker(代理)</strong>:Kafka集群中的每个服务器都被称为代理。代理负责存储和处理消息,生产者和消费者与代理进行通信。</p> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;"><strong style="color: rgb(37, 132, 181);">Topic(主题)</strong>:消息在Kafka中通过主题进行分类和组织。一个主题可以有多个分区,每个分区可以在不同的代理上进行复制,以实现容错性。</p> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;"><strong style="color: rgb(37, 132, 181);">Partition(分区)</strong>:主题可以被分割成多个分区,每个分区在磁盘上都有自己的存储空间。分区提供了消息的有序性和并行处理的能力。</p> </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">Kafka具有高吞吐量、持久性、可扩展性和容错性的特点,广泛应用于数据处理、实时流处理、日志收集、事件驱动架构等场景。它可以处理海量的数据流,并保证数据的完整性和可靠性。同时,Kafka提供了一组强大的API和工具,使得开发者能够轻松地构建、部署和管理基于Kafka的应用程序。</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.6194444444444445" src="/upload/70ce15e092914afdd8d1abcb5bae158d.png" data-type="png" data-w="1080" style="display: block;margin-right: auto;margin-left: auto;"> </figure> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 22px;"><span style="display: inline-block;"><span style="counter-increment: counterh2;color: rgb(159,205,208);border-bottom: 4px solid rgb(159,205,208);font-size: 18px;padding: 2px 4px;">3</span></span><span style="font-size: 18px;border-bottom: 4px solid rgb(37,132,181);padding: 2px 4px;color: rgb(37,132,181);">消息的顺序消费</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">Kafka的消息顺序消费是指消费者按照消息的顺序逐条消费消息的过程。Kafka的分区(Partition)是消息的基本单位,每个分区中的消息按照顺序进行存储。在一个分区中,消息的顺序是有序的,这意味着先发送的消息会被存储在分区的前部,而后发送的消息会被追加到分区的末尾。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">Kafka通过分区的方式实现消息的顺序性,消费者可以订阅一个或多个分区来消费消息。当消费者从分区中拉取消息时,Kafka会按照消息在分区中的顺序返回给消费者。这样就保证了消费者将按照消息的顺序进行消费。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">需要注意的是,Kafka的多个分区是并行处理的,每个分区的消息可以独立进行消费。因此,在多个分区并行消费的情况下,消费者之间的消息顺序可能无法保证。但是,对于单个分区的消息消费,Kafka会确保按照消息的顺序进行消费。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">为了实现消息的顺序消费,可以根据业务需求将相关消息发送到同一个分区,并且使用单个消费者实例来消费该分区的消息。这样就可以保证消息在整个分区中按照顺序进行处理。同时,Kafka还提供了分区器(Partitioner)机制,可以根据消息的键(key)来决定消息被发送到哪个分区,从而进一步控制消息的顺序消费。</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.5953703703703703" src="/upload/f052663a395beb92a355fb17add4be24.png" data-type="png" data-w="1080" style="display: block;margin-right: auto;margin-left: auto;"> </figure> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 22px;"><span style="display: inline-block;"><span style="counter-increment: counterh2;color: rgb(159,205,208);border-bottom: 4px solid rgb(159,205,208);font-size: 18px;padding: 2px 4px;">4</span></span><span style="font-size: 18px;border-bottom: 4px solid rgb(37,132,181);padding: 2px 4px;color: rgb(37,132,181);">如何保证消息的顺序消费</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">在Java中,可以使用Kafka的消费者API来实现消息的顺序消费。以下是几种可以考虑的方法:</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);"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;"><strong style="color: rgb(37, 132, 181);">单个分区消费:</strong> 创建一个单独的消费者实例来消费一个分区的消息。这样可以确保在单个分区内的消息按顺序消费。但是需要注意,如果有多个分区,不同分区的消息仍可能以并发方式进行消费。</p> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;"><strong style="color: rgb(37, 132, 181);">指定分区消费:</strong> 通过指定消费者订阅的特定分区,可以确保只消费指定分区的消息。这样,可以通过将相关消息发送到同一个分区来保证消息的顺序消费。</p> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;"><strong style="color: rgb(37, 132, 181);">按键分区:</strong> Kafka允许根据消息的键(key)来决定将消息发送到哪个分区。如果消息的键是相同的,Kafka会将它们发送到同一个分区。因此,可以根据消息的键来保证消息的顺序消费。</p> </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">无论选择哪种方法,都应该注意以下几点:</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);"> 设置消费者的 <code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">max.poll.records</code> 参数,确保每次拉取的消息数量合适,以避免因一次拉取的消息过多而导致处理速度过慢。 </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);"> 监听消费者的 <code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">onPartitionsRevoked</code> 事件,以便在重新分配分区时进行必要的清理和准备工作。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 使用 <code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">auto.offset.reset</code> 参数设置消费者的offset重置策略,以决定当消费者启动时从哪个offset开始消费。 </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">通过上述方法,结合合适的配置和实现,可以在Java中实现Kafka消息的顺序消费。</p> </section>
作者:微信小助手
<p style="text-align: center;"><img class="rich_pages wxw-img" data-galleryid="" data-ratio="0.7074074074074074" data-s="300,640" data-type="png" data-w="1080" style="height: auto !important;" src="/upload/d3022bf08a14b3f3e727c46a90f51e5a.png"></p> <p style="margin: 1.5em 8px;font-size: 14px;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.1em;">Redis 解析信息图</p> <h3 style="margin-top: 2em;margin-right: 8px;margin-bottom: 0.75em;padding-left: 8px;font-weight: bold;letter-spacing: normal;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.2;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 1.1em;">什么是 Redis?</h3> <p style="margin: 1.5em 8px;font-size: 14px;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.1em;">Redis("<strong style="line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;">RE</strong>mote <strong style="line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;">DI</strong>ctionary <strong style="line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;">S</strong>ervice" 的缩写)是一个开源的键值数据库服务器。</p> <p style="margin: 1.5em 8px;font-size: 14px;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.1em;">对 Redis 最准确的描述是它是一个数据结构服务器。Redis 的这种特定性质使其在开发人员中非常受欢迎和广泛采用。</p> <p style="margin: 1.5em 8px;font-size: 14px;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.1em;">与其对行进行迭代、排序和排列,不如从头开始使用数据结构来存储数据?早期,Redis 像 Memcached 一样使用,但随着 Redis 的改进,它变得可行于许多其他用例,包括发布-订阅机制、流处理和队列。</p> <figure style="margin: 1.5em 8px;font-size: 14px;letter-spacing: normal;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;"> <img class="rich_pages wxw-img" data-ratio="1.326851851851852" data-type="jpeg" data-w="1080" style="margin: 0.1em auto 0.5em;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-radius: 4px;display: block;height: auto !important;" title="null" src="/upload/726ed8fc9a6a8f3103c0c3d9e189d82e.jpg"> <figcaption style="text-align: center;color: rgb(136, 136, 136);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 0.8em;"> Redis-v2-separate-08.jpeg </figcaption> </figure> <p style="margin: 1.5em 8px;font-size: 14px;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.1em;">用于存储的 Redis 数据类型</p> <p style="margin: 1.5em 8px;font-size: 14px;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.1em;">主要地,Redis 是一个内存中的数据库,用作其他“真实”数据库(如 MySQL 或 PostgreSQL)前面的缓存,以帮助提高应用程序的性能。它充分利用了内存的速度,并减轻了中央应用程序数据库的负载,用于以下情况:</p> <p style="margin-bottom: 0px;padding-left: 1em;font-size: 14px;letter-spacing: normal;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;list-style: circle;"><span style="margin: 0.2em 8px;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;text-indent: -1em;display: block;"><span style="margin-right: 10px;">•</span>很少更改但经常请求的数据</span><span style="margin: 0.2em 8px;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;text-indent: -1em;display: block;"><span style="margin-right: 10px;">•</span>较不关键但经常演化的数据。</span></p> <p style="margin: 1.5em 8px;font-size: 14px;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.1em;">上述数据的示例可以包括会话或数据缓存以及仪表板的排行榜或汇总分析。</p> <figure style="margin: 1.5em 8px;font-size: 14px;letter-spacing: normal;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;"> <img class="rich_pages wxw-img" data-ratio="0.5518518518518518" data-type="jpeg" data-w="1080" style="margin: 0.1em auto 0.5em;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-radius: 4px;display: block;height: auto !important;" title="null" src="/upload/7c058b3bbbed1d2f429edbcc7c1401cf.jpg"> <figcaption style="text-align: center;color: rgb(136, 136, 136);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 0.8em;"> Redis-v2-separate-05.jpeg </figcaption> </figure> <p style="margin: 1.5em 8px;font-size: 14px;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.1em;">Redis 如何用于缓存</p> <p style="margin: 1.5em 8px;font-size: 14px;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.1em;">然而,对于许多用例,Redis 提供了足够的保证,可以用作一个功能齐全的主数据库。结合 Redis 插件和各种高可用性(HA)设置,Redis 作为数据库对于某些场景和工作负载变得非常有用。</p> <p style="margin: 1.5em 8px;font-size: 14px;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.1em;">另一个重要的方面是,Redis 模糊了缓存和数据存储之间的界限。在内存中读取和操作数据比在传统数据存储中使用 SSD 或 HDD 更快,这一点非常重要。</p> <figure style="margin: 1.5em 8px;font-size: 14px;letter-spacing: normal;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;"> <img class="rich_pages wxw-img" data-ratio="0.7074074074074074" data-type="jpeg" data-w="1080" style="margin: 0.1em auto 0.5em;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-radius: 4px;display: block;height: auto !important;" title="null" src="/upload/36133b5383e2ed1f27e505070fe995b3.jpg"> <figcaption style="text-align: center;color: rgb(136, 136, 136);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 0.8em;"> FXZjqMPVUAAqUfs-1.jpeg </figcaption> </figure> <p style="margin: 1.5em 8px;font-size: 14px;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.1em;">每位软件工程师都应该了解的重要延迟和带宽数据。</p> <p style="margin: 1.5em 8px;font-size: 14px;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.1em;">最初,Redis 最常与 Memcached 进行比较,后者在当时没有任何非易失性持久性。</p> <h4 style="margin: 2em 8px 0.5em;font-weight: bold;color: rgb(0, 0, 0);font-size: 1em;letter-spacing: normal;text-wrap: wrap;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;">Memcached</h4> <p style="margin: 1.5em 8px;font-size: 14px;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.1em;">Memcached 由 Brad Fitzpatrick 于 2003 年创建,比 Redis 提前了六年。它最初是一个 Perl 项目,后来被重写为 C 语言。它是当时的事实上的缓存工具。它与 Redis 的主要区别在于它缺乏数据类型和仅支持 LRU(最近最少使用)的有限驱逐策略。</p> <p style="margin: 1.5em 8px;font-size: 14px;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.1em;">另一个区别是,Redis 是单线程的,而 Memcached 是多线程的。在严格的缓存环境中,Memcached 可能性能不错,但在分布式集群中需要进行一些设置,而 Redis 则可以立即支持此功能。</p> <p style="margin: 1.5em 8px;font-size: 14px;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.1em;">下面是这两个缓存之间功能的当前比较。</p> <h3 style="margin-top: 2em;margin-right: 8px;margin-bottom: 0.75em;padding-left: 8px;font-weight: bold;letter-spacing: normal;text-wrap: wrap;text-align: left;color: rgb(63, 63, 63);line-height: 1.2;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 1.1em;">表格</h3> <section style="margin-bottom: 0px;padding-right: 8px;padding-left: 8px;height: 423.5px;color: rgb(0, 0, 0);font-family: "PingFang SC", "system-ui", Roboto, "Helvetica Neue", sans-serif;font-size: 14px;letter-spacing: normal;text-align: start;text-wrap: wrap;"> <table width="319"> <thead style="color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;background: rgba(0, 0, 0, 0.05);font-weight: bold;"> <tr> <td style="padding: 0.25em 0.5em;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);"><strong style="line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;">Memcached</strong></td> <td style="padding: 0.25em 0.5em;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);"><strong style="line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;">Redis</strong></td> <td style="padding: 0.25em 0.5em;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);"><br></td> </tr> </thead> <tbody> <tr> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">亚毫秒延迟</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">是</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">是</td> </tr> <tr> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">开发者易用性</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">是</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">是</td> </tr> <tr> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">数据分区</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">是</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">是</td> </tr> <tr> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">广泛支持的编程语言</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">是</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">是</td> </tr> <tr> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">高级数据结构</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">-</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">是</td> </tr> <tr> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">多线程架构</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">是</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">-</td> </tr> <tr> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">快照</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">-</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">是</td> </tr> <tr> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">复制</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">-</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">是</td> </tr> <tr> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">事务</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">-</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">是</td> </tr> <tr> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">发布/订阅</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">-</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">是</td> </tr> <tr> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">Lua 脚本</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">-</td> <td style="padding: 0.25em 0.5em;color: rgb(63, 63, 63);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;border-color: rgb(223, 223, 223);">是</td> </tr> <tr> <td style="padding: 0.25em 0.5e
作者:微信小助手
<section data-support="96编辑器" data-style-id="34263" style="margin-bottom: unset;"> <section style="margin-top: 10px;margin-bottom: 10px;"> <section data-width="100%"> <p style="text-align: center;"><img class="rich_pages wxw-img" data-ratio="0.08833333333333333" src="/upload/179616a5089cab3fc29e747a9c6cf0a4.png" data-w="600" style="width: auto;"></p> <p cid="n722" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-top: 0.8em;margin-bottom: 0.8em;white-space: pre-wrap; caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: Monaco, PingFangSC-Regular, "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;letter-spacing: normal;text-align: start;background-color: rgb(255, 255, 255); "><span style="font-size: 15px;">GitLab CI/CD是GitLab提供的持续集成和持续交付(CI/CD)工具,它允许开发团队在代码仓库中定义和管理自动化的流水线,以实现自动化构建、测试和部署应用程序的过程。通过GitLab CI/CD,开发团队可以更高效地进行软件开发和交付,提高开发速度和质量。</span></p> <p cid="n723" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-top: 0.8em;margin-bottom: 0.8em;white-space: pre-wrap; caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: Monaco, PingFangSC-Regular, "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;letter-spacing: normal;text-align: start;background-color: rgb(255, 255, 255); "><span style="font-size: 15px;">GitLab CI/CD的核心概念是流水线(Pipeline),它由一系列的阶段(Stage)和任务(Job)组成。每个任务可以执行一系列的操作,如构建代码、运行测试、生成文档、部署应用程序等。流水线可以根据代码仓库中的触发条件(如提交代码、合并请求等)自动触发执行,并提供了丰富的配置选项和扩展性,以满足不同项目的需求。</span></p> <p><br></p> <p><strong><span style="color: rgb(51, 51, 51);font-family: Monaco, PingFangSC-Regular, "Helvetica Neue", Helvetica, Arial, sans-serif;letter-spacing: normal;orphans: 4;text-align: start;caret-color: rgb(51, 51, 51);white-space: pre-wrap;background-color: rgb(255, 255, 255);font-size: 16px;">GitLab CI/CD流水线语法</span></strong></p> </section> </section> </section> <p cid="n114" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-top: 0.8em;margin-bottom: 0.8em;white-space: pre-wrap; caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: Monaco, PingFangSC-Regular, "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;letter-spacing: normal;text-align: start;background-color: rgb(255, 255, 255); "><span style="font-size: 15px;">下面是GitLab CI/CD流水线语法的完整解释:</span></p> <ol class="list-paddingleft-1" start="" cid="n115" mdtype="list" style=" margin-top: 0.8em;margin-bottom: 0.8em;padding-left: 30px; caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: Monaco, PingFangSC-Regular, "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;text-size-adjust: auto;background-color: rgb(255, 255, 255); "> <li style=" font-size: 15px; "><p cid="n117" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;">stages(阶段):使用<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">stages</code>关键字定义流水线的阶段,每个阶段代表流水线中的一个逻辑分组。例如:</span></p></li> </ol> <p cid="n117" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><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="bash"><code><span class="code-snippet_outer">stages:</span></code><code><span class="code-snippet_outer"> - build</span></code><code><span class="code-snippet_outer"> - <span class="code-snippet__built_in">test</span></span></code><code><span class="code-snippet_outer"> - deploy</span></code></pre> </section> <p><br></p> <ol class="list-paddingleft-1" start="2" cid="n119" mdtype="list" style=" margin-top: 0.8em;margin-bottom: 0.8em;padding-left: 30px; caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: Monaco, PingFangSC-Regular, "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;text-size-adjust: auto;background-color: rgb(255, 255, 255); "> <li style=" font-size: 15px; "><p cid="n121" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;">jobs(任务):在每个阶段中,可以定义一个或多个任务(<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">jobs</code>),每个任务代表流水线中的一个操作。任务可以并行执行或按顺序执行。例如:</span></p></li> </ol> <p cid="n121" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><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="properties"><code><span class="code-snippet_outer"><span class="code-snippet__attr">build</span>:<span class="code-snippet__string"></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attr">stage</span>: <span class="code-snippet__string">build</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attr">script</span>:<span class="code-snippet__string"></span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__meta">-</span> <span class="code-snippet__string">echo "Building the application..."</span></span></code></pre> </section> <p><br></p> <ol class="list-paddingleft-1" start="3" cid="n123" mdtype="list" style=" margin-top: 0.8em;margin-bottom: 0.8em;padding-left: 30px; caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: Monaco, PingFangSC-Regular, "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;text-size-adjust: auto;background-color: rgb(255, 255, 255); "> <li style=" font-size: 15px; "><p cid="n125" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;">script(脚本):在任务中,使用<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">script</code>关键字定义要执行的脚本命令。脚本可以是任何可执行的命令或脚本语言。例如:</span></p></li> </ol> <p><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="bash"><code><span class="code-snippet_outer">script:</span></code><code><span class="code-snippet_outer"> - echo "Building the application..."</span></code><code><span class="code-snippet_outer"> - npm install</span></code><code><span class="code-snippet_outer"> - npm run build</span></code></pre> </section> <p><br></p> <ol class="list-paddingleft-1" start="4" cid="n127" mdtype="list" style=" margin-top: 0.8em;margin-bottom: 0.8em;padding-left: 30px; caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: Monaco, PingFangSC-Regular, "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;text-size-adjust: auto;background-color: rgb(255, 255, 255); "> <li style=" font-size: 15px; "><p cid="n129" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;">before_script(前置脚本):在任务执行之前,可以使用<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">before_script</code>关键字定义要在每个任务之前执行的脚本命令。例如:</span></p></li> </ol> <p><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="sql"><code><span class="code-snippet_outer">before_script:</span></code><code><span class="code-snippet_outer"> - echo "Setting up environment..."</span></code><code><span class="code-snippet_outer"> - apt-get install -y some-package</span></code></pre> </section> <p><span style="display: none;line-height: 0px;"></span><br></p> <ol class="list-paddingleft-1" start="5" cid="n131" mdtype="list" style=" margin-top: 0.8em;margin-bottom: 0.8em;padding-left: 30px; caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: Monaco, PingFangSC-Regular, "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;text-size-adjust: auto;background-color: rgb(255, 255, 255); "> <li cid="n132" mdtype="list_item" style=" font-size: 15px; "><p cid="n133" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;">after_script(后置脚本):在任务执行之后,可以使用<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">after_script</code>关键字定义要在每个任务之后执行的脚本命令。例如:</span></p></li> </ol> <p><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="bash"><code><span class="code-snippet_outer">after_script:</span></code><code><span class="code-snippet_outer"> - echo "Cleaning up..."</span></code><code><span class="code-snippet_outer"> - rm -rf some-directory</span></code></pre> </section> <p><span style="display: none;line-height: 0px;"></span><br></p> <ol class="list-paddingleft-1" start="6" cid="n135" mdtype="list" style=" margin-top: 0.8em;margin-bottom: 0.8em;padding-left: 30px; caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: Monaco, PingFangSC-Regular, "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;text-size-adjust: auto;background-color: rgb(255, 255, 255); "> <li cid="n136" mdtype="list_item" style=" font-size: 15px; "><p cid="n137" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;">variables(变量):使用<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">variables</code>关键字定义流水线中的环境变量。环境变量可以在脚本中使用,用于传递参数或配置信息。例如:</span></p></li> </ol> <p><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="properties"><code><span class="code-snippet_outer">variables:</span></code><code><span class="code-snippet_outer"> ENVIRONMENT: production</span></code><code><span class="code-snippet_outer"> API_KEY: $API_KEY</span></code></pre> </section> <p><br></p> <ol class="list-paddingleft-1" start="7" cid="n139" mdtype="list" style=" margin-top: 0.8em;margin-bottom: 0.8em;padding-left: 30px; caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: Monaco, PingFangSC-Regular, "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;text-size-adjust: auto;background-color: rgb(255, 255, 255); "> <li cid="n140" mdtype="list_item" style=" font-size: 15px; "><p cid="n141" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;">rules(规则):使用<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">rules</code>关键字定义任务的触发规则。可以根据条件来决定是否执行任务。例如:</span></p></li> </ol> <p><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="properties"><code><span class="code-snippet_outer">build:</span></code><code><span class="code-snippet_outer"> stage: build</span></code><code><span class="code-snippet_outer"> script:</span></code><code><span class="code-snippet_outer"> - echo "Building the application..."</span></code><code><span class="code-snippet_outer"> rules:</span></code><code><span class="code-snippet_outer"> - changes</span></code><code><span class="code-snippet_outer"> - exists:</span></code><code><span class="code-snippet_outer"> - Dockerfile</span></code></pre> </section> <p><br></p> <ol class="list-paddingleft-1" start="8" cid="n143" mdtype="list" style=" margin-top: 0.8em;margin-bottom: 0.8em;padding-left: 30px; caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: Monaco, PingFangSC-Regular, "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;text-size-adjust: auto;background-color: rgb(255, 255, 255); "> <li cid="n144" mdtype="list_item" style=" font-size: 15px; "><p cid="n145" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;">artifacts(产物):使用<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">artifacts</code>关键字定义任务产生的产物(如构建产物、测试报告等)。产物可以在后续的任务中使用或存档。例如:</span></p></li> </ol> <p><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="properties"><code><span class="code-snippet_outer">build:</span></code><code><span class="code-snippet_outer"> stage: build</span></code><code><span class="code-snippet_outer"> script:</span></code><code><span class="code-snippet_outer"> - echo "Building the application..."</span></code><code><span class="code-snippet_outer"> artifacts:</span></code><code><span class="code-snippet_outer"> paths:</span></code><code><span class="code-snippet_outer"> - dist/</span></code></pre> </section> <p><br></p> <ol class="list-paddingleft-1" start="9" cid="n147" mdtype="list" style=" margin-top: 0.8em;margin-bottom: 0.8em;padding-left: 30px; caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: Monaco, PingFangSC-Regular, "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;text-size-adjust: auto;background-color: rgb(255, 255, 255); "> <li cid="n148" mdtype="list_item" style=" font-size: 15px; "><p cid="n149" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;">dependencies(依赖):使用<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">dependencies</code>关键字定义任务的依赖关系。可以指定一个或多个任务作为当前任务的依赖,确保依赖任务执行成功后再执行当前任务。例如:</span></p></li> </ol> <p><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="bash"><code><span class="code-snippet_outer">test:</span></code><code><span class="code-snippet_outer"> stage: test</span></code><code><span class="code-snippet_outer"> script:</span></code><code><span class="code-snippet_outer"> - echo "Running tests..."</span></code><code><span class="code-snippet_outer"> dependencies:</span></code><code><span class="code-snippet_outer"> - build</span></code></pre> </section> <p><br></p> <p><span style="caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: Monaco, PingFangSC-Regular, "Helvetica Neue", Helvetica, Arial, sans-serif;letter-spacing: normal;orphans: 4;text-align: start;white-space: pre-wrap;text-size-adjust: auto;background-color: rgb(255, 255, 255);font-size: 15px;">以上是GitLab CI/CD流水线语法的主要要点和关键字。你可以根据你的项目需求和实际情况进行配置和扩展。在实际使用中,你还可以使用更多的关键字和功能,如缓存、环境、扩展、触发器等,以满足更复杂的需求。</span></p> <p><span style="caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: Monaco, PingFangSC-Regular, "Helvetica Neue", Helvetica, Arial, sans-serif;letter-spacing: normal;orphans: 4;text-align: start;white-space: pre-wrap;text-size-adjust: auto;background-color: rgb(255, 255, 255);font-size: 15px;"><br></span></p> <p><strong><span style="caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: Monaco, PingFangSC-Regular, "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;letter-spacing: normal;orphans: 4;text-align: start;white-space: pre-wrap;text-size-adjust: auto;background-color: rgb(255, 255, 255);">基于GitLab CI/CD流水线部署到K8S流水线实战</span></strong></p> <p><span style="caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: Monaco, PingFangSC-Regular, "Helvetica Neue", Helvetica, Arial, sans-serif;letter-spacing: normal;orphans: 4;text-align: start;white-space: pre-wrap;text-size-adjust: auto;background-color: rgb(255, 255, 255);font-size: 15px;">以下是一个基于GitLab CI/CD流水线的示例,包括拉代码、安装依赖、镜像构建、推送到私服仓库、Sonar代码检测、部署Kubernetes、扫描镜像漏洞、发送钉钉构建成功或失败通知:</span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="bash"><code><span class="code-snippet_outer">stages:</span></code><code><span class="code-snippet_outer"> - build</span></code><code><span class="code-snippet_outer"> - <span class="code-snippet__built_in">test</span></span></code><code><span class="code-snippet_outer"> - deploy</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer">variables:</span></code><code><span class="code-snippet_outer"> DOCKER_REGISTRY: registry.example.com</span></code><code><span class="code-snippet_outer"> DOCKER_NAMESPACE: myapp</span></code><code><span class="code-snippet_outer"> DOCKER_IMAGE_NAME: myapp</span></code><code><span class="code-snippet_outer"> DOCKER_IMAGE_TAG: latest</span></code><code><span class="code-snippet_outer"> K8S_NAMESPACE: myapp</span></code><code><span class="code-snippet_outer"> K8S_DEPLOYMENT_NAME: myapp</span></code><code><span class="code-snippet_outer"> K8S_SERVICE_NAME: myapp</span></code><code><span class="code-snippet_outer"> K8S_CONTAINER_PORT: 80</span></code><code><span class="code-snippet_outer"> K8S_REPLICAS: 3</span></code><code><span class="code-snippet_outer"> DOCKER_USERNAME: username</span></code><code><span class="code-snippet_outer"> DOCKER_PASSWORD: <span class="code-snippet__variable">$DOCKER_PASSWORD</span></span></code><code><span class="code-snippet_outer"> NEXUS_USERNAME: nexus_username</span></code><code><span class="code-snippet_outer"> NEXUS_PASSWORD: <span class="code-snippet__variable">$NEXUS_PASSWORD</span></span></code><code><span class="code-snippet_outer"> SONAR_TOKEN: <span class="code-snippet__variable">$SONAR_TOKEN</span></span></code><code><span class="code-snippet_outer"> DINGTALK_ACCESS_TOKEN: <span class="code-snippet__variable">$DINGTALK_ACCESS_TOKEN</span></span></code><code><span class="code-snippet_outer"> DINGTALK_SECRET: <span class="code-snippet__variable">$DINGTALK_SECRET</span></span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer">before_script:</span></code><code><span class="code-snippet_outer"> - <span class="code-snippet__built_in">echo</span> <span class="code-snippet__string">"Setting up environment..."</span></span></code><code><span class="code-snippet_outer"> - apk add --no-cache curl jq</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer">build:</span></code><code><span class="code-snippet_outer"> stage: build</span></code><code><span class="code-snippet_outer"> script:</span></code><code><span class="code-snippet_outer"> - <span class="code-snippet__built_in">echo</span> <span class="code-snippet__string">"Building the application..."</span></span></code><code><span class="code-snippet_outer"> - npm install</span></code><code><span class="code-snippet_outer"> - docker build -t <span class="code-snippet__variable">$DOCKER_REGISTRY</span>/<span class="code-snippet__variable">$DOCKER_NAMESPACE</span>/<span class="code-snippet__variable">$DOCKER_IMAGE_NAME</span>:<span class="code-snippet__variable">$DOCKER_IMAGE_TAG</span> .</span></code><code><span class="code-snippet_outer"> - docker login -u <span class="code-snippet__variable">$DOCKER_USERNAME</span> -p <span class="code-snippet__variable">$DOCKER_PASSWORD</span> <span class="code-snippet__variable">$DOCKER_REGISTRY</span></span></code><code><span class="code-snippet_outer"> - docker push <span class="code-snippet__variable">$DOCKER_REGISTRY</span>/<span class="code-snippet__variable">$DOCKER_NAMESPACE</span>/<span class="code-snippet__variable">$DOCKER_IMAGE_NAME</span>:<span class="code-snippet__variable">$DOCKER_IMAGE_TAG</span></span></code><code><span class="code-snippet_outer"> - <span class="code-snippet__built_in">echo</span> <span class="code-snippet__string">"Pushing the Docker image to Nexus..."</span></span></code><code><span class="code-snippet_outer"> - docker tag <span class="code-snippet__variable">$DOCKER_REGISTRY</span>/<span class="code-snippet__variable">$DOCKER_NAMESPACE</span>/<span class="code-snippet__variable">$DOCKER_IMAGE_NAME</span>:<span class="code-snippet__variable">$DOCKER_IMAGE_TAG</span> <span class="code-snippet__variable">$DOCKER_REGISTRY</span>/<span class="code-snippet__variable">$DOCKER_NAMESPACE</span>/<span class="code-snippet__variable">$DOCKER_IMAGE_NAME</span>:<span class="code-snippet__variable">$DOCKER_IMAGE_TAG</span></span></code><code><span class="code-snippet_outer"> - docker login -u <span class="code-snippet__variable">$NEXUS_USERNAME</span> -p <span class="code-snippet__variable">$NEXUS_PASSWORD</span> <span class="code-snippet__variable">$DOCKER_REGISTRY</span></span></code><code><span class="code-snippet_outer"> - docker push <span class="code-snippet__variable">$DOCKER_REGISTRY</span>/<span class="code-snippet__variable">$DOCKER_NAMESPACE</span>/<span class="code-snippet__variable">$DOCKER_IMAGE_NAME</span>:<span class="code-snippet__variable">$DOCKER_IMAGE_TAG</span></span></code><code><span class="code-snippet_outer"> artifacts:</span></code><code><span class="code-snippet_outer"> paths:</span></code><code><span class="code-snippet_outer"> - dist/</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"><span class="code-snippet__built_in">test</span>:</span></code><code><span class="code-snippet_outer"> stage: <span class="code-snippet__built_in">test</span></span></code><code><span class="code-snippet_outer"> image: sonarsource/sonar-scanner-cli:latest</span></code><code><span class="code-snippet_outer"> script:</span></code><code><span class="code-snippet_outer"> - <span class="code-snippet__built_in">echo</span> <span class="code-snippet__string">"Running Sonar analysis..."</span></span></code><code><span class="code-snippet_outer"> - sonar-scanner -Dsonar.login=<span class="code-snippet__variable">$SONAR_TOKEN</span></span></code><code><span class="code-snippet_outer"> only:</span></code><code><span class="code-snippet_outer"> - master</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer">deploy:</span></code><code><span class="code-snippet_outer"> stage: deploy</span></code><code><span class="code-snippet_outer"> image: bitnami/kubectl:latest</span></code><code><span class="code-snippet_outer"> script:</span></code><code><span class="code-snippet_outer"> - <span class="code-snippet__built_in">echo</span> <span class="code-snippet__string">"Deploying the application..."</span></span></code><code><span class="code-snippet_outer"> - kubectl apply -f k8s/deployment.yaml -n <span class="code-snippet__variable">$K8S_NAMESPACE</span></span></code><code><span class="code-snippet_outer"> - kubectl apply -f k8s/service.yaml -n <span class="code-snippet__variable">$K8S_NAMESPACE</span></span></code><code><span class="code-snippet_outer"> environment:</span></code><code><span class="code-snippet_outer"> name: production</span></code><code><span class="code-snippet_outer"> url: http://<span class="code-snippet__variable">$K8S_SERVICE_NAME</span>.<span class="code-snippet__variable">$K8S_NAMESPACE</span>.svc.cluster.local:<span class="code-snippet__variable">$K8S_CONTAINER_PORT</span></span></code><code><span class="code-snippet_outer"> only:</span></code><code><span class="code-snippet_outer"> - master</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer">scan:</span></code><code><span class="code-snippet_outer"> stage: deploy</span></code><code><span class="code-snippet_outer"> image: aquasec/trivy:latest</span></code><code><span class="code-snippet_outer"> script:</span></code><code><span class="code-snippet_outer"> - <span class="code-snippet__built_in">echo</span> <span class="code-snippet__string">"Scanning Docker image for vulnerabilities..."</span></span></code><code><span class="code-snippet_outer"> - trivy <span class="code-snippet__variable">$DOCKER_REGISTRY</span>/<span class="code-snippet__variable">$DOCKER_NAMESPACE</span>/<span class="code-snippet__variable">$DOCKER_IMAGE_NAME</span>:<span class="code-snippet__variable">$DOCKER_IMAGE_TAG</span></span></code><code><span class="code-snippet_outer"> only:</span></code><code><span class="code-snippet_outer"> - master</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer">notify:</span></code><code><span class="code-snippet_outer"> stage: deploy</span></code><code><span class="code-snippet_outer"> image: curlimages/curl:latest</span></code><code><span class="code-snippet_outer"> script:</span></code><code><span class="code-snippet_outer"> - <span class="code-snippet__built_in">echo</span> <span class="code-snippet__string">"Sending notification..."</span></span></code><code><span class="code-snippet_outer"> - <span class="code-snippet__built_in">export</span> MESSAGE=$(<span class="code-snippet__built_in">echo</span> -e <span class="code-snippet__string">"GitLab CI/CD pipeline for *<span class="code-snippet__variable">$CI_PROJECT_NAME</span>* (<span class="code-snippet__variable">$CI_COMMIT_REF_NAME</span>) *<span class="code-snippet__variable">$CI_PIPELINE_STATUS</span>*.\n\nView pipeline details at <span class="code-snippet__variable">$CI_PIPELINE_URL</span>"</span>)</span></code><code><span class="code-snippet_outer"> - <span class="code-snippet__built_in">export</span> SIGN=$(<span class="code-snippet__built_in">echo</span> -n <span class="code-snippet__string">"<span class="code-snippet__variable">$MESSAGE</span><span class="code-snippet__variable">$DINGTALK_SECRET</span>"</span> | openssl dgst -sha256 -hmac <span class="code-snippet__variable">$DINGTALK_SECRET</span> | awk <span class="code-snippet__string">'{print $2}'</span>)</span></code><code><span class="code-snippet_outer"> - curl -s -X POST <span class="code-snippet__string">"https://oapi.dingtalk.com/robot/send?access_token=<span class="code-snippet__variable">$DINGTALK_ACCESS_TOKEN</span>&timestamp=<span class="code-snippet__variable">$(date +%s000)</span>&sign=<span class="code-snippet__variable">$SIGN</span>"</span> \</span></code><code><span class="code-snippet_outer"> -H <span class="code-snippet__string">'Content-Type: application/json'</span> \</span></code><code><span class="code-snippet_outer"> -d <span class="code-snippet__string">"{\"msgtype\": \"text\",\"text\": {\"content\": \"<span class="code-snippet__variable">$MESSAGE</span>\"}}"</span></span></code><code><span class="code-snippet_outer"> when: on_failure</span></code></pre> </section> <p><span style="font-size: 15px;background-color: rgb(255, 255, 255);color: rgb(51, 51, 51);font-family: Monaco, PingFangSC-Regular, "Helvetica Neue", Helvetica, Arial, sans-serif;letter-spacing: normal;orphans: 4;text-align: start;caret-color: rgb(51, 51, 51);white-space-collapse: preserve;">当使用上述给出的流水线时,以下是每个阶段的详细步骤解释:</span><br></p> <ol class="list-paddingleft-1" cid="n206" mdtype="list" style=" margin-top: 0.8em;margin-bottom: 0.8em;padding-left: 30px; caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: Monaco, PingFangSC-Regular, "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;letter-spacing: normal;text-align: start;text-wrap: wrap;text-size-adjust: auto;background-color: rgb(255, 255, 255); "> <li cid="n207" mdtype="list_item" style=" font-size: 15px; "><p cid="n208" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;"><code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">build</code>阶段:</span></p></li> <ul class="list-paddingleft-1" cid="n209" mdtype="list" data-mark="-" style=" padding-left: 30px; "> <li cid="n210" mdtype="list_item" style=" font-size: 15px; "><p cid="n211" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;">安装依赖:执行<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">npm install</code>命令安装项目的依赖项。</span></p></li> <li cid="n212" mdtype="list_item" style=" font-size: 15px; "><p cid="n213" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;">构建镜像:使用<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">docker build</code>命令构建Docker镜像,镜像名称为<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">$DOCKER_REGISTRY/$DOCKER_NAMESPACE/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG</code>。</span></p></li> <li cid="n214" mdtype="list_item" style=" font-size: 15px; "><p cid="n215" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;">登录到Docker仓库:使用<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">docker login</code>命令登录到Docker仓库,用户名为<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">$DOCKER_USERNAME</code>,密码为<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">$DOCKER_PASSWORD</code>。</span></p></li> <li cid="n216" mdtype="list_item" style=" font-size: 15px; "><p cid="n217" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;">推送镜像:使用<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">docker push</code>命令将构建的镜像推送到Docker仓库。</span></p></li> <li cid="n218" mdtype="list_item" style=" font-size: 15px; "><p cid="n219" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;">推送到Nexus私服:将构建的镜像重新标记为<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">$DOCKER_REGISTRY/$DOCKER_NAMESPACE/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG</code>,然后使用<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">docker login</code>命令登录到Nexus私服,用户名为<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">$NEXUS_USERNAME</code>,密码为<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">$NEXUS_PASSWORD</code>,最后使用<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">docker push</code>命令将镜像推送到Nexus私服。</span></p></li> </ul> <li cid="n220" mdtype="list_item" style=" font-size: 15px; "><p cid="n221" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;"><code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">test</code>阶段:</span></p></li> <ul class="list-paddingleft-1" cid="n222" mdtype="list" data-mark="-" style=" padding-left: 30px; "> <li cid="n223" mdtype="list_item" style=" font-size: 15px; "><p cid="n224" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;">运行Sonar代码检测:使用<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">sonar-scanner</code>命令运行Sonar代码检测,需要提供Sonar的访问令牌(<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">$SONAR_TOKEN</code>)。</span></p></li> </ul> <li cid="n225" mdtype="list_item" style=" font-size: 15px; "><p cid="n226" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;"><code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">deploy</code>阶段:</span></p></li> <ul class="list-paddingleft-1" cid="n227" mdtype="list" data-mark="-" style=" padding-left: 30px; "> <li cid="n228" mdtype="list_item" style=" font-size: 15px; "><p cid="n229" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;">部署应用:使用<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">kubectl apply</code>命令将Kubernetes部署文件<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">k8s/deployment.yaml</code>和<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">k8s/service.yaml</code>应用到Kubernetes集群中的命名空间<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">$K8S_NAMESPACE</code>。</span></p></li> <li cid="n230" mdtype="list_item" style=" font-size: 15px; "><p cid="n231" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;">设置环境变量:设置环境变量<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">name</code>为"production",<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">url</code>为应用的访问URL。</span></p></li> </ul> <li cid="n232" mdtype="list_item" style=" font-size: 15px; "><p cid="n233" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;"><code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">scan</code>阶段:</span></p></li> <ul class="list-paddingleft-1" cid="n234" mdtype="list" data-mark="-" style=" padding-left: 30px; "> <li cid="n235" mdtype="list_item" style=" font-size: 15px; "><p cid="n236" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;">扫描镜像漏洞:使用<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">trivy</code>命令对Docker镜像<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">$DOCKER_REGISTRY/$DOCKER_NAMESPACE/$DOCKER_IMAGE_NAME:$DOCKER_IMAGE_TAG</code>进行安全扫描。</span></p></li> </ul> <li cid="n237" mdtype="list_item" style=" font-size: 15px; "><p cid="n238" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;"><code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">notify</code>阶段:</span></p></li> <ul class="list-paddingleft-1" cid="n239" mdtype="list" data-mark="-" style=" padding-left: 30px; "> <li cid="n240" mdtype="list_item" style=" font-size: 15px; "><p cid="n241" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-bottom: 0.5rem;white-space-collapse: preserve; "><span style="font-size: 15px;">发送通知:使用<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">curl</code>命令发送通知到钉钉群组,通知内容包括GitLab CI/CD流水线的状态和详情。发送通知的URL为<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">https://oapi.dingtalk.com/robot/send?access_token=$DINGTALK_ACCESS_TOKEN</code>,签名使用<code style="font-family: var(--monospace);border-width: 1px;border-style: solid;border-color: rgb(231, 234, 237);background-color: rgb(243, 244, 244);border-radius: 3px;padding-right: 2px;padding-left: 2px;font-size: 0.9em;">$DINGTALK_SECRET</code>进行加密。</span></p></li> </ul> </ol> <p cid="n242" mdtype="paragraph" style=" line-height: inherit;orphans: 4;margin-top: 0.8em;margin-bottom: 0.8em;white-space: pre-wrap; caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: Monaco, PingFangSC-Regular, "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 16px;letter-spacing: normal;text-align: start;background-color: rgb(255, 255, 255); "><span style="font-size: 15px;">请根据你的实际情况和配置,修改示例中的变量和命令,确保与你的项目和环境相匹配。</span></p> <p><br></p> <section data-support="96编辑器" data-style-id="27643" style="margin-bottom: unset;"> <section style="margin-top: 10px;margin-bottom: 10px;"> <p style="margin-right: auto;margin-left: auto;"><img class="rich_pages wxw-img" data-ratio="0.0625" src="/upload/617d39ec2e74b7bf9681d2bd8f8b9e2.png" data-w="640" style="width: auto;"></p> <section data-support="96编辑器" data-style-id="29194" style="margin-bottom: unset;"> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;"> <section style="border-width: 1px;border-style: solid;border-color: rgb(128, 204, 197);border-radius: 30px;display: inline-block;padding: 3px 25px;color: rgb(75, 146, 147);"> <p style="letter-spacing: 2px;">往期推荐</p> </section> <section style="display: flex;justify-content: center;align-items:center;"> <section style="width:1px;height:11px;background-color:#80ccc5;"> <br> </section> <section style="margin-left:3px;width:1px;height:11px;background-color:#80ccc5;"> <br> </section> <section style="margin-left:73px;width:1px;height:11px;background-color:#80ccc5;"> <br> </section> <section style="margin-left:3px;width:1px;height:11px;background-color:#80ccc5;"> <br> </section> </section> <section style="border-width: 1px;border-style: solid;border-color: rgb(128, 204, 197);border-radius: 10px;color: rgb(75, 146, 147);padding: 5px 15px 15px;"> <section style="margin-top:10px;"> <section style="border-bottom: 1px solid rgb(117, 200, 192);padding-top: 3px;padding-bottom: 3px;"> <section style="display: flex;align-items:center;"> <section style="height: 0px;border-top: 8px solid transparent;border-right-color: #75c8c0;border-bottom: 8px solid transparent;border-left: 8px solid #75c8c0;transform: rotateZ(0deg);"> <br> </section> <section style="color:#333;margin-left:5px;width:95%;" data-width="95%"> <p style="letter-spacing: 2px;text-align: left;"><a href="https://mp.weixin.qq.com/s?__biz=Mzk0OTI3MDg5MA==&mid=2247485576&idx=1&sn=03f3161690dea207618f3c2a7338229a&chksm=c35ba88df42c219bd4085a73df9dfe8e0e598056862ff19b99ac6512103b69ecb67cca41bc24&token=174191270&lang=zh_CN&scene=21#wechat_redirect" target="_blank" title="DevOps 与 SysOps" textvalue="DevOps 与 SysOps" style="font-size: 13px;text-decoration: underline;" data-linktype="2">DevOps 与 SysOps</a><br></p> </section> </section> </section> </section> <section style="margin-top:10px;"> <section style="border-bottom: 1px solid rgb(117, 200, 192);padding-top: 3px;padding-bottom: 3px;"> <section style="display: flex;align-items:center;"> <section style="height: 0px;border-top: 8px solid transparent;border-right-color: #75c8c0;border-bottom: 8px solid transparent;border-left: 8px solid #75c8c0;transform: rotateZ(0deg);"> <br> </section> <section style="color:#333;margin-left:5px;width:95%;" data-width="95%"> <p style="letter-spacing: 2px;text-align: left;"><a href="https://mp.weixin.qq.com/s?__biz=Mzk0OTI3MDg5MA==&mid=2247485562&idx=1&sn=85b49b415ffe810f26485f9e7d4f0875&chksm=c35ba87ff42c2169e5f95d87708f9ff7a7b15dbed4e271213c4da07186d1285c298a3b90b7a2&token=683779055&lang=zh_CN&scene=21#wechat_redirect" target="_blank" title="DevOps中的Argo CD — 灾难恢复" textvalue="DevOps中的Argo CD — 灾难恢复" style="font-size: 13px;text-decoration: underline;" data-linktype="2">DevOps中的Argo CD — 灾难恢复</a><br></p> </section> </section> </section> </section> <section style="margin-top:10px;"> <section style="border-bottom: 1px solid rgb(117, 200, 192);padding-top: 3px;padding-bottom: 3px;"> <section style="display: flex;align-items:center;"> <section style="height: 0px;border-top: 8px solid transparent;border-right-color: #75c8c0;border-bottom: 8px solid transparent;border-left: 8px solid #75c8c0;transform: rotateZ(0deg);"> <br> </section> <section style="color:#333;margin-left:5px;width:95%;" data-width="95%"> <p style="letter-spacing: 2px;text-align: left;"><a href="https://mp.weixin.qq.com/s?__biz=Mzk0OTI3MDg5MA==&mid=2247485583&idx=1&sn=61df278cd7d37962a621533cb889fa05&chksm=c35ba88af42c219c454b5b38aa00122a7c9db219748712507eafda3f3249abfd0f33b8a38dba&token=174191270&lang=zh_CN&scene=21#wechat_redirect" target="_blank" title="云原生CNCF生态蓝图" textvalue="云原生CNCF生态蓝图" style="font-size: 13px;text-decoration: underline;" data-linktype="2">云原生CNCF生态蓝图</a><br></p> </section> </section> </section> </section> <section style="margin-top:10px;"> <section style="border-bottom: 1px solid rgb(117, 200, 192);padding-top: 3px;padding-bottom: 3px;"> <section style="display: flex;align-items:center;"> <section style="height: 0px;border-top: 8px solid transparent;border-right-color: #75c8c0;border-bottom: 8px solid transparent;border-left: 8px solid #75c8c0;transform: rotateZ(0deg);"> <br> </section> <section style="color:#333;margin-left:5px;width:95%;" data-width="95%"> <p style="letter-spacing: 2px;text-align: left;"><a href="https://mp.weixin.qq.com/s?__biz=Mzk0OTI3MDg5MA==&mid=2247485258&idx=1&sn=3bd9a3cde876c0107af0e2be64b9620d&chksm=c35ba74ff42c2e5939b9d0e1a9cd6d1bfba9fb637c88e53aeb7a49cfe5676c7af3c11794ea14&token=337198691&lang=zh_CN&scene=21#wechat_redirect" target="_blank" title="Deploying ArgoCD/Prometheus/Grafana/— Including Dashboards" textvalue="Deploying ArgoCD/Prometheus/Grafana/— Including Dashboards" style="font-size: 13px;text-decoration: underline;" data-linktype="2">Deploying ArgoCD/Prometheus/Grafana/— Including Dashboards</a><br></p> </section> </section> </section> </section> <section style="margin-top:10px;"> <section style="border-bottom: 1px solid rgb(117, 200, 192);padding-top: 3px;padding-bottom: 3px;"> <section style="display: flex;align-items:center;"> <section style="height: 0px;border-top: 8px solid transparent;border-right-color: #75c8c0;border-bottom: 8px solid transparent;border-left: 8px solid #75c8c0;transform: rotateZ(0deg);"> <br> </section> <section style="color:#333;margin-left:5px;width:95%;" data-width="95%"> <p style="letter-spacing: 2px;text-align: left;"><a href="https://mp.weixin.qq.com/s?__biz=Mzk0OTI3MDg5MA==&mid=2247485455&idx=1&sn=32e77972b39ee1246709eb97e7da06a6&chksm=c35ba80af42c211ce6cf489d6c52f332da7e12de82351265bee363009420b7dcb39b9adc0021&token=494176944&lang=zh_CN&scene=21#wechat_redirect" target="_blank" title="Cloud Native 云原生 | 概念解读" textvalue="Cloud Native 云原生 | 概念解读" style="font-size: 13px;text-decoration: underline;" data-linktype="2">Cloud Native 云原生 | 概念解读</a></p> </section> </section> </section> </section> </section> </section> </section> </section> </section> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>