作者:微信小助手
<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="padding-right: 10px;padding-left: 10px;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;letter-spacing: 2px;line-height: 1.75em;" data-mpa-powered-by="yiban.io"> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;margin: 1em 4px;">数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过�
作者:微信小助手
<p style="max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;caret-color: rgb(51, 51, 51);font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;text-size-adjust: auto;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;box-sizing: border-box;letter-spacing: 0.544px;color: rgb(249, 110, 87);font-size: 18px;overflow-wrap: break-word !important;">女主宣言</strong></p> <section style="max-width: 100%;box-sizing: border-box;letter-spacing: 0.544px;white-space: normal;caret-color: rgb(51, 51, 51);font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;text-size-adjust: auto;background-color: rgb(255, 255, 255);font-size: 16px;overflow-wrap: break-word !important;"> <section powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section powered-by="xiumi.us" style="margin-top: -5px;max-width: 100%;box-sizing: border-box;letter-spacing: 0.544px;text-align: left;line-height: 1;transform: translate3d(0px, 0px, 0px);overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box;width: 0px;display: inline-block;vertical-align: bottom;border-bottom: 0.7em solid rgb(244, 244, 244);overflow-wrap: break-word !important;border-left: 0.45em solid transparent !important;border-right: 0.45em solid transparent !important;"> <br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> </section> <section style="max-width: 100%;box-sizing: border-box;width: 0px;display: inline-block;vertical-align: bottom;border-bottom: 0.7em solid rgb(244, 244, 244);overflow-wrap: break-word !important;border-left: 0.45em solid transparent !important;border-right: 0.45em solid transparent !important;"> <br s
作者:微信小助手
<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="line-height: 1.6;word-break: break-word;text-align: left;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;letter-spacing: 0.5444px;padding-left: 5px;padding-right: 5px;" data-mpa-powered-by="yiban.io"> <blockquote data-tool="mdnice编辑器" style="border-top: none;border-right: none;border-bottom: none;font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);border-left-width: 2px;padding: 8px 10px 4px 15px;background: rgb(255, 249, 249);border-left-color: rgb(239, 112, 96);margin-top: 0px;margin-bottom: 20px;letter-spacing: 0.5444px;"> <p style="text-align: justify;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;margin-bottom: 10px;color: rgb(51, 51, 51);line-height: 30px;letter-spacing: 0.5444px;"><br mpa-from-tpl="t"></p> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-mpa-template="t" mpa-from-tpl="t"> <p style="clear: both;min-height: 1em;color: inherit;font-size: inherit;letter-spacing: 2px;word-spacing: 2px;line-height: inherit;text-align: right;"><img class="rich_pages js_insertlocalimg" data-cropselx1="0" data-cropselx2="578" data-cropsely1="0" data-cropsely2="215" data-ratio="0.36100746268656714" data-s="300,640" src="/upload/2a27b849b18b6f2dc9890c15129e9c7a.jpg" data-type="jpeg" data-w="2144" style="height: 209px;color: rgb(0, 82, 255);text-align: center;width: 578px;"><span style="color: rgb(0, 82, 255);">本文公众号来源:水滴与银弹</span></p> <p style="clear: both;min-height: 1em;color: inherit;font-size: inherit;letter-spacing: 2px;word-spacing: 2px;line-height: inherit;text-align: right;"><span style="color: rgb(0, 82, 255);">作者:Magic Kaito</span></p> <p style="clear: both;min-height: 1em;color: inherit;font-size: inherit;letter-spacing: 2px;word-spacing: 2px;line-height: inherit;text-align: right;"><span style="color: rgb(0, 82, 255);">本文已收录至我的</span><strong mpa-from-tpl="t" style="color: rgb(51, 51, 51);font-size: 17px;"><span style="font-size: 14px;color: rgb(217, 33, 66);">GitHub</span></strong></p> </section> </section> <p><br mpa-from-tpl="t"></p> <p style="text-align: justify;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;margin-bottom: 10px;color: rgb(51, 51, 51);line-height: 30px;letter-spacing: 0.5444px;">阅读本文大约需要 15 分钟。</p> </blockquote> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">我经常听到很多人讨论,关于「把 Redis 当作队列来用是否合适」的问题。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">有些人表示赞成,他们认为 Redis 很轻量,用作队列很方便。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">也些人则反对,认为 Redis 会「丢」数据,最好还是用「专业」的队列中间件更稳妥。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">究竟哪种方案更好呢?</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">这篇文章,我就和你聊一聊把 Redis 当作队列,究竟是否合适这个问题。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">我会从简单到复杂,一步步带你梳理其中的细节,把这个问题真正的讲清楚。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">看完这篇文章后,我希望你对这个问题你会有全新的认识。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;"><span style="color: rgb(255, 104, 39);">在文章的最后,我还会告诉你关于「技术选型」的思路,文章有点长,希望你可以耐心读完。</span></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.4188861985472155" src="/upload/ce16e990976c12ae111f2633901c6ec.png" data-type="png" data-w="826" style="display: block;margin: 15px auto;"> </figure> <h1 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 24px;margin-top: 50px;margin-bottom: 35px;"><span style="font-size: 20px;color: rgb(234, 84, 41);letter-spacing: 0.5444px;padding-bottom: 10px;border-bottom: 2px solid rgb(234, 84, 41);">从最简单的开始:List 队列</span></h1> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">首先,我们先从最简单的场景开始讲起。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">如果你的业务需求足够简单,想把 Redis 当作队列来使用,肯定最先想到的就是使用 List 这个数据类型。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">因为 List 底层的实现就是一个「链表」,在头部和尾部操作元素,时间复杂度都是 O(1),这意味着它非常符合消息队列的模型。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">如果把 List 当作队列,你可以这么来用。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">生产者使用 LPUSH 发布消息:</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;"><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;">127.0.0.1:6379> LPUSH queue msg1<br>(integer) 1<br>127.0.0.1:6379> LPUSH queue msg2<br>(integer) 2<br></code></pre> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">消费者这一侧,使用 RPOP 拉取消息:</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;"><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;">127.0.0.1:6379> RPOP queue<br>"msg1"<br>127.0.0.1:6379> RPOP queue<br>"msg2"<br></code></pre> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">这个模型非常简单,也很容易理解。</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.29515418502202645" src="/upload/8e3f5e997bd95784ef05dc57e70a135f.jpg" data-type="jpeg" data-w="681" style="display: block;margin: 15px auto;"> </figure> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">但这里有个小问题,当队列中已经没有消息了,消费者在执行 RPOP 时,会返回 NULL。</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;"><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;">127.0.0.1:6379> RPOP queue<br>(nil) // 没消息了<br></code></pre> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">而我们在编写消费者逻辑时,一般是一个「死循环」,这个逻辑需要不断地从队列中拉取消息进行处理,伪代码一般会这么写:</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;"><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: #c678dd;line-height: 26px;">while</span> true:<br> msg = redis.rpop(<span style="color: #98c379;line-height: 26px;">"queue"</span>)<br> // 没有消息,继续循环<br> <span style="color: #c678dd;line-height: 26px;">if</span> msg == null:<br> <span style="color: #c678dd;line-height: 26px;">continue</span><br> // 处理消息<br> handle(msg)<br></code></pre> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">如果此时队列为空,那消费者依旧会频繁拉取消息,这会造成「CPU 空转」,不仅浪费 CPU 资源,还会对 Redis 造成压力。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">怎么解决这个问题呢?</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">也很简单,当队列为空时,我们可以「休眠」一会,再去尝试拉取消息。代码可以修改成这样:</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;"><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: #c678dd;line-height: 26px;">while</span> true:<br> msg = redis.rpop(<span style="color: #98c379;line-height: 26px;">"queue"</span>)<br> // 没有消息,休眠<span style="color: #d19a66;line-height: 26px;">2</span>s<br> <span style="color: #c678dd;line-height: 26px;">if</span> msg == null:<br> sleep(<span style="color: #d19a66;line-height: 26px;">2</span>)<br> <span style="color: #c678dd;line-height: 26px;">continue</span><br> // 处理消息 <br> handle(msg)<br></code></pre> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">这就解决了 CPU 空转问题。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">这个问题虽然解决了,但又带来另外一个问题:当消费者在休眠等待时,有新消息来了,那消费者处理新消息就会存在「延迟」。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">假设设置的休眠时间是 2s,那新消息最多存在 2s 的延迟。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">要想缩短这个延迟,只能减小休眠的时间。但休眠时间越小,又有可能引发 CPU 空转问题。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">鱼和熊掌不可兼得。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">那如何做,既能及时处理新消息,还能避免 CPU 空转呢?</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">Redis 是否存在这样一种机制:如果队列为空,消费者在拉取消息时就「阻塞等待」,一旦有新消息过来,就通知我的消费者立即处理新消息呢?</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">幸运的是,Redis 确实提供了「阻塞式」拉取消息的命令:BRPOP / BLPOP,这里的 B 指的是阻塞(Block)。</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.23641703377386197" src="/upload/4689bf886241045ab589a2932a50a2b6.jpg" data-type="jpeg" data-w="681" style="display: block;margin: 15px auto;"> </figure> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">现在,你可以这样来拉取消息了:</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;"><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: #c678dd;line-height: 26px;">while</span> true:<br> // 没消息阻塞等待,<span style="color: #d19a66;line-height: 26px;">0</span>表示不设置超时时间<br> msg = redis.brpop(<span style="color: #98c379;line-height: 26px;">"queue"</span>, <span style="color: #d19a66;line-height: 26px;">0</span>)<br> <span style="color: #c678dd;line-height: 26px;">if</span> msg == null:<br> <span style="color: #c678dd;line-height: 26px;">continue</span><br> // 处理消息<br> handle(msg)<br></code></pre> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">使用 BRPOP 这种阻塞式方式拉取消息时,还支持传入一个「超时时间」,如果设置为 0,则表示不设置超时,直到有新消息才返回,否则会在指定的超时时间后返回 NULL。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">这个方案不错,既兼顾了效率,还避免了 CPU 空转问题,一举两得。</p> <blockquote data-tool="mdnice编辑器" style="border-top: none;border-right: none;border-bottom: none;font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);border-left-width: 2px;padding: 8px 10px 4px 15px;background: rgb(255, 249, 249);border-left-color: rgb(239, 112, 96);margin-top: 0px;margin-bottom: 20px;letter-spacing: 0.5444px;"> <p style="text-align: justify;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;margin-bottom: 10px;color: rgb(51, 51, 51);line-height: 30px;letter-spacing: 0.5444px;">注意:如果设置的超时时间太长,这个连接太久没有活跃过,可能会被 Redis Server 判定为无效连接,之后 Redis Server 会强制把这个客户端踢下线。所以,采用这种方案,客户端要有重连机制。</p> </blockquote> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">解决了消息处理不及时的问题,你可以再思考一下,这种队列模型,有什么缺点?</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">我们一起来分析一下:</p> <ol data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;" class="list-paddingleft-2"> <li> <section style="margin-bottom: 10px;line-height: 25px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;color: rgb(74, 74, 74);letter-spacing: 0.5444px;"> <strong style="color: rgb(34, 34, 34);letter-spacing: 0.5444px;">不支持重复消费</strong>:消费者拉取消息后,这条消息就从 List 中删除了,无法被其它消费者再次消费,即不支持多个消费者消费同一批数据 </section></li> <li> <section style="margin-bottom: 10px;line-height: 25px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;color: rgb(74, 74, 74);letter-spacing: 0.5444px;"> <strong style="color: rgb(34, 34, 34);letter-spacing: 0.5444px;">消息丢失</strong>:消费者拉取到消息后,如果发生异常宕机,那这条消息就丢失了 </section></li> </ol> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">第一个问题是功能上的,使用 List 做消息队列,它仅仅支持最简单的,一组生产者对应一组消费者,不能满足多组生产者和消费者的业务场景。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">第二个问题就比较棘手了,因为从 List 中 POP 一条消息出来后,这条消息就会立即从链表中删除了。也就是说,无论消费者是否处理成功,这条消息都没办法再次消费了。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">这也意味着,如果消费者在处理消息时异常宕机,那这条消息就相当于丢失了。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">针对这 2 个问题怎么解决呢?我们一个个来看。</p> <h1 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 24px;margin-top: 50px;margin-bottom: 35px;"><span style="font-size: 20px;color: rgb(234, 84, 41);letter-spacing: 0.5444px;padding-bottom: 10px;border-bottom: 2px solid rgb(234, 84, 41);">发布/订阅模型:Pub/Sub</span></h1> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">从名字就能看出来,这个模块是 Redis 专门是针对「发布/订阅」这种队列模型设计的。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">它正好可以解决前面提到的第一个问题:重复消费。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">即多组生产者、消费者的场景,我们来看它是如何做的。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">Redis 提供了 PUBLISH / SUBSCRIBE 命令,来完成发布、订阅的操作。</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.40360610263522884" src="/upload/3ff79cedbdd607a614c79e1058fded9d.jpg" data-type="jpeg" data-w="721" style="display: block;margin: 15px auto;"> </figure> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">假设你想开启 2 个消费者,同时消费同一批数据,就可以按照以下方式来实现。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">首先,使用 SUBSCRIBE 命令,启动 2 个消费者,并「订阅」同一个队列。</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;"><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;">// 2个消费者 都订阅一个队列<br>127.0.0.1:6379> SUBSCRIBE queue<br>Reading messages... (press Ctrl-C to quit)<br>1) "subscribe"<br>2) "queue"<br>3) (integer) 1<br></code></pre> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">此时,2 个消费者都会被阻塞住,等待新消息的到来。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">之后,再启动一个生产者,发布一条消息。</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;"><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;">127.0.0.1:6379> PUBLISH queue msg1<br>(integer) 1<br></code></pre> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">这时,2 个消费者就会解除阻塞,收到生产者发来的新消息。</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;"><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;">127.0.0.1:6379> SUBSCRIBE queue<br>// 收到新消息<br>1) "message"<br>2) "queue"<br>3) "msg1"<br></code></pre> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">看到了么,使用 Pub/Sub 这种方案,既支持阻塞式拉取消息,还很好地满足了多组消费者,消费同一批数据的业务需求。</p> <p data-tool="mdnice编辑器" style="text-align: justify;line-height: 30px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 0.5444px;margin-bottom: 20px;">除此之外,Pub/Sub 还提供了「匹配订阅」模式,允许消费者根据一定规则,订阅「多个」自己感兴趣的队列。</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;"><code style="overflow-x: auto;padding: 16px;color: #abb2bf;display: -webkit-box;font-family: Operator Mono, Cons
作者:微信小助手
<section class="mp_profile_iframe_wrp"> <mpprofile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-id="MzU5NDg5MzM5NQ==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/BdQKIO6XpMXZa2U8FCySWQFV4y6HRtFxddNQ6d2hDu4cjqr8wOfrtBDKayTeRia44dtR9wJErHNGACdkMz8xvyQ/0?wx_fmt=png" data-nickname="波哥的IT人生" data-alias="itboge" data-signature="十五年IT老兵!全栈开发、运维开发、devops,python、vue等视频教学,IT行业技术与资讯分享!"></mpprofile> </section> <p style="box-sizing: border-box;margin-top: 1.5em;margin-bottom: 1.5em;font-size: 16px;color: rgb(62, 62, 62);line-height: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">一. 前情提要</p> <p style="box-sizing: border-box;margin-top: 1.5em;margin-bottom: 1.5em;font-size: 16px;color: rgb(62, 62, 62);line-height: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">以下试验以及说明是经过试验确定了的,准确!!另外,如果想知道每个参数的真正含义,建议看官网</p> <p style="box-sizing: border-box;margin-top: 1.5em;margin-bottom: 1.5em;font-size: 16px;color: rgb(62, 62, 62);line-height: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">解决的问题:</p> <p style="box-sizing: border-box;margin-top: 1.5em;margin-bottom: 1.5em;font-size: 16px;color: rgb(62, 62, 62);line-height: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">1,当一个节点(Linux设备)挂了,2个VIP都浮动到一个节点上</p> <p style="box-sizing: border-box;margin-top: 1.5em;margin-bottom: 1.5em;font-size: 16px;color: rgb(62, 62, 62);line-height: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">2,当这个节点(Linux设备)好了,由于业务有一定的延时,所以还不想浮动IP立马漂移回来</p> <p style="box-sizing: border-box;margin-top: 1.5em;margin-bottom: 1.5em;font-size: 16px;color: rgb(62, 62, 62);line-height: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">3,如果一个节点的业务(设备上运行的业务进程)完蛋了,需要自己主动交出VIP</p> <p style="box-sizing: border-box;margin-top: 1.5em;margin-bottom: 1.5em;font-size: 16px;color: rgb(62, 62, 62);line-height: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">4,等自己节点的业务(设备上运行的业务进程)又好了,那么不能立马夺权,而是有一个过渡再夺权</p> <p style="box-sizing: border-box;margin-top: 1.5em;margin-bottom: 1.5em;font-size: 16px;color: rgb(62, 62, 62);line-height: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">二. 官方配置说明</p> <p style="box-sizing: border-box;margin-top: 1.5em;margin-bottom: 1.5em;font-size: 16px;color: rgb(62, 62, 62);line-height: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">官方文档:https://www.keepalived.org/manpage.html</p> <p style="box-sizing: border-box;margin-top: 1.5em;margin-bottom: 1.5em;font-size: 16px;color: rgb(62, 62, 62);line-height: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">概述:</p> <p style="box-sizing: border-box;margin-top: 1.5em;margin-bottom: 1.5em;font-size: 16px;color: rgb(62, 62, 62);line-height: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">keepalived的具体实现原理这里就不做阐述,但是从其配置文件的角度大致将其工作模块分成两部分: 全局部分,和VRRP实例部分。</p> <p style="box-sizing: border-box;margin-top: 1.5em;margin-bottom: 1.5em;font-size: 16px;color: rgb(62, 62, 62);line-height: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">全局部分,顾名思义就是整体相关的配置;</p> <p style="box-sizing: border-box;margin-top: 1.5em;margin-bottom: 1.5em;font-size: 16px;color: rgb(62, 62, 62);line-height: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">VRRP实例部分:</p> <pre style="box-sizing: border-box;font-size: 16px;color: rgb(62, 62, 62);line-height: inherit;text-align: start;background-color: rgb(255, 255, 255);"><code style="box-sizing: border-box;margin-right: 2px;margin-left: 2px;padding: 0.5em;font-size: 14px;color: white;line-height: 18px;border-radius: 0px;background: rgb(51, 51, 51);display: block;font-family: Consolas, Inconsolata, Courier, monospace;overflow-x: auto;letter-spacing: 0px;overflow-wrap: normal !important;word-break: normal !important;overflow-y: auto !important;">首先,keepalived通过创建一个个VRRP实例来实现浮动IP的管理,一个VRRP实例可以看做是一个连接实例(使用VRRP协议);<br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">一个实例对应一个VIP,一台设备可以配置多个VRRP实例即参与多个VIP的抢占;<br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">然后,具有相同VRRP实例配置的一对设备,会因为实例匹配而成功配对;<br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">最后,通过协商得到谁是master谁是slave,以及谁来占有VIP。<br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"></code></pre> <p style="box-sizing: border-box;margin-top: 1.5em;margin-bottom: 1.5em;font-size: 16px;color: rgb(62, 62, 62);line-height: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">全局配置部分</p> <ol style="padding-left: 32px;list-style-position: initial;list-style-image: initial;font-size: 16px;color: rgb(62, 62, 62);line-height: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);" class="list-paddingleft-2"> <li style="box-sizing: border-box;margin-bottom: 0.5em;font-size: inherit;color: inherit;line-height: inherit;"><p><span style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;">预定义一个脚本以及脚本管理方式,之后用于VRRP实例引用</span></p></li> </ol> <pre style="box-sizing: border-box;font-size: 16px;color: rgb(62, 62, 62);line-height: inherit;text-align: start;background-color: rgb(255, 255, 255);"><code style="box-sizing: border-box;margin-right: 2px;margin-left: 2px;padding: 0.5em;font-size: 14px;color: white;line-height: 18px;border-radius: 0px;background: rgb(51, 51, 51);display: block;font-family: Consolas, Inconsolata, Courier, monospace;overflow-x: auto;letter-spacing: 0px;overflow-wrap: normal !important;word-break: normal !important;overflow-y: auto !important;"><span style="box-sizing: border-box;font-size: inherit;color: rgb(255, 255, 170);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">vrrp_script</span> <SCRIPT_NAME> {<br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="box-sizing: border-box;font-size: inherit;color: rgb(136, 136, 136);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">#脚本的路径,或者直接就是脚本本身</span><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="box-sizing: border-box;font-size: inherit;color: rgb(255, 255, 170);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">script</span> <STRING>|<QUOTED-STRING><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="box-sizing: border-box;font-size: inherit;color: rgb(136, 136, 136);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"># 间隔多长时间执行一次脚本</span><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> interval <INTEGER><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="box-sizing: border-box;font-size: inherit;color: rgb(136, 136, 136);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">#脚本执行如果没有正确返回,则这段时间后就算超时,然后算作是failed了</span><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> timeout <INTEGER> <br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="box-sizing: border-box;font-size: inherit;color: rgb(136, 136, 136);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"># adjust priority by this weight, (default: 0).For description of reverse, see track_script.</span><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="box-sizing: border-box;font-size: inherit;color: rgb(136, 136, 136);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"># 'weight 0 reverse' will cause the vrrp instance to be down when the script is up, and vice versa.</span><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> weight <INTEGER:-<span style="box-sizing: border-box;font-size: inherit;color: rgb(211, 99, 99);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">253</span>..<span style="box-sizing: border-box;font-size: inherit;color: rgb(211, 99, 99);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">253</span>> [reverse]<br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="box-sizing: border-box;font-size: inherit;color: rgb(136, 136, 136);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"># required number of successes for OK transition</span><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> rise <INTEGER><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="box-sizing: border-box;font-size: inherit;color: rgb(136, 136, 136);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"># required number of successes for KO transition</span><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> fall <INTEGER><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="box-sizing: border-box;font-size: inherit;color: rgb(136, 136, 136);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"># 以哪个用户身份去执行脚本的人是谁</span><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> user USERNAME [GROUPNAME]<br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="box-sizing: border-box;font-size: inherit;color: rgb(136, 136, 136);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"># 假设初始时脚本是执行失败的</span><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> init_fail<br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">}<br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"></code></pre> <ol start="2" style="padding-left: 32px;list-style-position: initial;list-style-image: initial;font-size: 16px;color: rgb(62, 62, 62);line-height: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);" class="list-paddingleft-2"> <li style="box-sizing: border-box;margin-bottom: 0.5em;font-size: inherit;color: inherit;line-height: inherit;"><p><span style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;">VRRP实例部分</span></p></li> </ol> <pre style="box-sizing: border-box;font-size: 16px;color: rgb(62, 62, 62);line-height: inherit;text-align: start;background-color: rgb(255, 255, 255);"><code style="box-sizing: border-box;margin-right: 2px;margin-left: 2px;padding: 0.5em;font-size: 14px;color: white;line-height: 18px;border-radius: 0px;background: rgb(51, 51, 51);display: block;font-family: Consolas, Inconsolata, Courier, monospace;overflow-x: auto;letter-spacing: 0px;overflow-wrap: normal !important;word-break: normal !important;overflow-y: auto !important;"><span style="box-sizing: border-box;font-size: inherit;color: rgb(136, 136, 136);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"># Ignore VRRP interface faults (default unset)</span><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">dont_track_primary <span style="box-sizing: border-box;font-size: inherit;color: rgb(136, 136, 136);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">#表示的含义是,一旦接口有问题,则忽略之,否则keepalived的代码中对链路有做检查,发现链路down则进入fault状态,于是将放弃所有浮动ip</span><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="box-sizing: border-box;font-size: inherit;color: rgb(136, 136, 136);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"># optional, monitor these as well. go to FAULT state if any of these go down if unweighted.</span><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="box-sizing: border-box;font-size: inherit;color: rgb(136, 136, 136);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"># When a weight is specified in track_interface, instead of setting the vrrp instance to the FAULT state in case of failure, its priority will be</span><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="box-sizing: border-box;font-size: inherit;color: rgb(136, 136, 136);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"># increased by the weight when the interface is up (for positive weights), or decreased by the weight's absolute value when the interface is down</span><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="box-sizing: border-box;font-size: inherit;color: rgb(136, 136, 136);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"># (for negative weights), unless reverse is specified, in which case the direction of adjustment of the priority is reversed.</span><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="box-sizing: border-box;font-size: inherit;color: rgb(136, 136, 136);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"># The weight must be comprised between -253 and +253 inclusive.0 is the default behaviour which means that a failure implies a</span><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="box-sizing: border-box;font-size: inherit;color: rgb(136, 136, 136);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"># FAULT state. The common practice is to use positive weights to count a limited number of good services so that the server with the highest count</span><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="box-sizing: border-box;font-size: inherit;color: rgb(136, 136, 136);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"># becomes master. Negative weights are better to count unexpected failures among a high number of interfaces, as it will not saturate even with high</span><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="box-sizing: border-box;font-size: inherit;color: rgb(136, 136, 136);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"># number of interfaces. Use reverse to increase priority if an interfaces is down</span><br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">track_interface {<br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> eth0<br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> eth1<br style="box-sizing: border-box;font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> &nbs
作者:微信小助手
<section style="box-sizing: border-box;font-style: normal;font-weight: 400;text-align: justify;font-size: 16px;"> <section style="box-sizing: border-box;max-width: 100%;" powered-by="xiumi.us"> <section style="display: inline;max-width: 100%;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: block;width: auto;vertical-align: top;box-sizing: border-box;max-width: 100%;"> <section class="mp_profile_iframe_wrp" powered-by="xiumi.us" style="box-sizing: border-box;"> <mpprofile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-id="MzIyMTUwMDMyOQ==" data-headimg="//img.xiumi.us/xmi/ua/pZrj/i/c11e39f16bf9d10a6ad57108b216b78a-sz_19101.png" data-nickname="RancherLabs" data-signature="Rancher是一个开源的企业级Kubernetes管理平台,实现了Kubernetes集群在混合云+本地数据中心的集中部署与管理。" style="box-sizing: border-box;"></mpprofile> </section> <section style="text-align: unset;font-size: 14px;color: rgb(182, 182, 182);box-sizing: border-box;max-width: 100%;" powered-by="xiumi.us"> <p style="text-align: center;white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><strong style="box-sizing: border-box;">点击上方卡片关注公众号并设为星标✨</strong></p> <p style="text-align: center;white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><strong style="box-sizing: border-box;">即可及时获取K8S干货哟</strong></p> </section> <section style="text-align: unset;line-height: 2;box-sizing: border-box;max-width: 100%;" powered-by="xiumi.us"> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><span style="font-size: 15px;box-sizing: border-box;"><br style="box-sizing: border-box;"></span></p> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><span style="font-size: 15px;box-sizing: border-box;">从Rancher 2.5起,Rancher借助Fleet提供了大规模交付的GitOps功能,允许用户使用GitOps的方法管理其集群的状态。</span></p> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><span style="font-size: 15px;box-sizing: border-box;"><br style="box-sizing: border-box;"></span></p> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><span style="font-size: 15px;box-sizing: border-box;">金丝雀发布是一个被软件开发者广泛使用的方法,它可以用来向一部分用户发布新版本的应用程序,并根据可用性、延迟或自定义指标等指标来扩大规模,进而为更多用户提供服务。在本文中,我们将探索如何使用持续交付来为你的应用程序工作负载执行金丝雀发布。</span></p> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><span style="font-size: 15px;box-sizing: border-box;">实际的金丝雀发布将由一个名为Flagger的项目执行。Flagger作为Kubernetes operator运行。它允许用户指定一个自定义对象,该对象会通知Flagger观察一个部署并创建额外的主要部署(primary deployment)和金丝雀部署。作为本文的一部分,我们将使用Flagger与Istio作为服务网格。</span></p> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><span style="font-size: 15px;box-sizing: border-box;">简而言之,当我们创建一个部署时,Flagger会将该部署克隆到一个主部署。然后它修改与原始部署相关的服务以指向这个新的主部署。该主部署本身会被缩减到0。</span></p> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><span style="font-size: 15px;box-sizing: border-box;">Flagger使用Istio virtualservices来执行实际的金丝雀发布。当一个新版本的应用程序被部署时,Flagger将原始部署缩减到原始规格,并将金丝雀服务关联到部署。</span></p> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><span style="font-size: 15px;box-sizing: border-box;">现在,一定比例的流量被路由到这个金丝雀服务。基于预定义的指标,Flagger开始将越来越多的流量路由到这个金丝雀服务。一旦100%的流量被迁移到金丝雀服务,主部署就会以原始部署相同的规格重新创建。</span></p> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><span style="font-size: 15px;box-sizing: border-box;">接下来,将更新virtualservice以将100%的流量返回到主服务。在流量转换之后,原始部署被缩减为0,Flagger operator等待并监控后续的部署更新。</span></p> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> </section> <section style="max-width: 100%;box-sizing: border-box;" powered-by="xiumi.us"> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;max-width: 100%;"> <section style="display: inline;max-width: 100%;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline;box-sizing: border-box;"> <section style="max-width: 100%;vertical-align: middle;display: inline-block;line-height: 0;width: 10%;height: auto;box-sizing: border-box;"> <img data-ratio="0.8814815" data-w="1080" src="/upload/60358879c6b9b7345a7836526c068340.jpg" style="vertical-align: middle;max-width: 100%;width: 100%;box-sizing: border-box;" width="100%" data-type="jpeg"> </section> </section> </section> </section> </section> <section style="text-align: unset;line-height: 2;box-sizing: border-box;max-width: 100%;" powered-by="xiumi.us"> <p style="text-align: center;white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><strong style="box-sizing: border-box;"><span style="font-size: 18px;color: rgb(0, 117, 168);box-sizing: border-box;">借助Flagger执行金丝雀发布</span></strong></p> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><span style="font-size: 15px;box-sizing: border-box;">为了开始使用Flagger,我们需要执行以下操作:</span></p> <p style="white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> </section> <section style="max-width: 100%;box-sizing: border-box;" powered-by="xiumi.us"> <section style="font-size: 15px;line-height: 2;box-sizing: border-box;max-width: 100%;"> <section style="display: inline;max-width: 100%;box-sizing: border-box;" powered-by="xiumi.us"> <section style="max-width: 100%;box-sizing: border-box;"> <section style="text-align: unset;list-style-type: decimal;box-sizing: border-box;max-width: 100%;"> <section style="display: inline;max-width: 100%;box-sizing: border-box;" powered-by="xiumi.us"> <ol style="box-sizing: border-box;" class="list-paddingleft-2"> <li style="box-sizing: border-box;"><p style="margin: 0px;padding: 0px;box-sizing: border-box;">设置监控和Istio</p></li> <li style="box-sizing: border-box;"><p style="margin: 0px;padding: 0px;box-sizing: border-box;">设置Flagger和flagger-loadtest</p></li> <li style="box-sizing: border-box;"><p style="margin: 0px;padding: 0px;box-sizing: border-box;">部署一个demo程序并执行金丝雀发布</p></li> </ol> </section> </section> </section> </section> </section> </section> <section style="max-width: 100%;box-sizing: border-box;" powered-by="xiumi.us"> <section style="text-align: unset;white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;max-width: 100%;"> <section style="display: inline;max-width: 100%;box-sizing: border-box;" powered-by="xiumi.us"> <section style="margin: 0px;padding: 0px;box-sizing: border-box;max-width: 100%;"> <p style="margin: 0px;padding: 0px;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> </section> </section> </section> </section> <section style="max-width: 100%;box-sizing: border-box;" powered-by="xiumi.us"> <section style="margin-top: 10px;margin-bottom: 10px;text-align: left;box-sizing: border-box;max-width: 100%;"> <section style="display: inline-block;max-width: 100%;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;vertical-align: top;box-sizing: border-box;max-width: 100%;"> <section style="display: inline-block;vertical-align: middle;width: auto;max-width: 100%;box-sizing: border-box;"> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="max-width: 100%;display: inline-block;box-sizing: border-box;"> <section style="display: inline-block;vertical-align: middle;width: auto;max-width: 100%;box-sizing: border-box;"> <section style="display: inline-block;box-sizing: border-box;" powered-by="xiumi.us"> <section style="text-align: unset;display: inline-block;vertical-align: middle;color: rgb(0, 117, 168);box-sizing: border-box;max-width: 100%;"> <p style="margin: 0px;padding: 0px;box-sizing: border-box;"><strong>1<strong style="box-sizing: border-box;">.设置</strong></strong><strong style="box-sizing: border-box;">监控和Istio</strong></p> </section> </section> </section> </section> </section> </section> <section style="display: inline-block;vertical-align: middle;width: auto;max-width: 100%;box-sizing: border-box;"> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="max-width: 100%;display: inline-block;box-sizing: border-box;"> <section style="display: inline-block;vertical-align: middle;width: auto;box-sizing: border-box;max-width: 100%;"> <section style="max-width: 100%;display: inline-block;box-sizing: border-box;" powered-by="xiumi.us"> <section style="width: 0px;border-left: 8px solid rgb(0, 117, 168);border-top: 5px solid transparent;border-bottom: 5px solid transparent;margin-right: 3px;margin-left: 5px;display: inline-block;vertical-align: middle;box-sizing: border-box;max-width: 100%;"> <section> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> </section> </section> </section> <section style="display: inline-block;vertical-align: middle;width: auto;max-width: 100%;box-sizing: border-box;"> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="max-width: 100%;display: inline-block;box-sizing: border-box;"> <section style="display: inline-block;vertical-align: middle;width: auto;box-sizing: border-box;max-width: 100%;"> <section style="max-width: 100%;display: inline-block;box-sizing: border-box;" powered-by="xiumi.us"> <section style="width: 0px;border-left: 8px solid rgb(255, 255, 255);border-top: 4px solid transparent;border-bottom: 4px solid transparent;display: inline-block;vertical-align: middle;margin-right: -9px;transform: rotate(0deg);-webkit-transform: rotate(0deg);-moz-transform: rotate(0deg);-o-transform: rotate(0deg);box-sizing: border-box;max-width: 100%;"> <section> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> </section> </section> </section> <section style="display: inline-block;vertical-align: middle;width: auto;max-width: 100%;box-sizing: border-box;"> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="max-width: 100%;display: inline-block;box-sizing: border-box;"> <section style="display: inline-block;vertical-align: middle;width: auto;max-width: 100%;box-sizing: border-box;"> <section style="max-width: 100%;display: inline-block;box-sizing: border-box;" powered-by="xiumi.us"> <section style="width: 0px;border-left: 10px solid rgb(0, 117, 168);border-top: 6px solid transparent;border-bottom: 6px solid transparent;display: inline-block;vertical-align: middle;box-sizing: border-box;max-width: 100%;"> <section> <svg viewbox="0 0 1 1" style="float:left;line-height:0;width:0;vertical-align:top;"></svg> </section> </section> </section> </section> </section> </section> </section> </section> </section> </section> </section> <section style="display: block;width: auto;vertical-align: top;line-height: 2;box-sizing: border-box;max-width: 100%;" powered-by="xiumi.us"> <section style="text-align: unset;white-space: normal;margin: 0px;padding: 0px;box-sizing: border-box;max-width: 100%;" powered-by="xiumi.us"> <p style="margin: 0px;padding: 0px;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="margin: 0px;padding: 0px;box-sizing: border-box;"><span style="font-size: 15px;box-sizing: border-box;">为了设置</span><span style="color: rgb(230, 25, 131);font-size: 15px;box-sizing: border-box;background-color: rgb(240, 237, 246);">monitoring</span><span style="font-size: 15px;box-sizing: border-box;">和</span><span style="color: rgb(230, 25, 131);font-size: 15px;box-sizing: border-box;background-color: rgb(240, 237, 246);">istio</span><span style="font-size: 15px;box-sizing: border-box;">,我们将在持续交付中设置几个<span style="color: rgb(29, 35, 41);box-sizing: border-box;">ClusterGroups</span>:</span></p> <p style="margin: 0px;padding: 0px;box-sizing: border-box;"><br style="box-sizing: border-box;"></p> <p style="margin: 0px;padding: 0px;box-sizing: border-box;"><strong style="box-sizing: border-box;"><span style="font-size: 15px;box-sizing: border-box;">监控</span></strong></p> <p style="margin: 0px;padding: 0px;box-sizing: border-box;"><span style="font-size: 15px;box-sizing: border-box;"></span></p> </section> <section style="max-width: 100%;box-sizing: border-box;" powered-by="xiumi.us"> <section style="text-align: unset;box-sizing: border-box;max-width: 100%;"> <section style="display: inline;max-width: 100%;box-sizing: border-box;" powered-by="xiumi.us"> <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 style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"><span class="code-snippet__attr" style="box-sizing: border-box;">apiVersion</span>: <span class="code-snippet__string" style="box-sizing: border-box;">fleet.cattle.io/v1alpha1</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"><span class="code-snippet__attr" style="box-sizing: border-box;">kind</span>: <span class="code-snippet__string" style="box-sizing: border-box;">ClusterGroup</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"><span class="code-snippet__attr" style="box-sizing: border-box;">metadata</span>:<span class="code-snippet__string" style="box-sizing: border-box;"></span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__attr" style="box-sizing: border-box;">name</span>: <span class="code-snippet__string" style="box-sizing: border-box;">monitoring</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"> <span class="code-snippet__attr" style="box-sizing: border-box;">namespace</span>: <span class="code-snippet__string" style="box-sizing: border-box;">fleet-default</span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;"><span class="code-snippet__attr" style="box-sizing: border-box;">spec</span>:<span class="code-snippet__string" style="box-sizing: border-box;"></span></span></code><code style="box-sizing: border-box;"><span class="code-snippet_outer" style="box-sizing: border-box;">
作者:微信小助手
<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="padding-right: 10px;padding-left: 10px;overflow-wrap: break-word;text-align: left;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;line-height: 1.6;letter-spacing: 0.034em;color: rgb(63, 63, 63);font-size: 16px;" data-mpa-powered-by="yiban.io"> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 23px;color: rgb(74, 74, 74);line-height: 1.75em;">《对线面试官》系列目前已经连载<strong style="line-height: 1.75em;">20</strong>篇啦!进度是<strong style="line-height: 1.75em;">一周更新两篇</strong>,欢迎持续关注</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;" class="list-paddingleft-2"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a href="https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247483821&idx=1&sn=e9003410a8d3c8a092de0c4d2002bedd&scene=21#wechat_redirect" style="overflow-wrap: break-word;font-weight: bold;color: rgb(60, 112, 198);border-bottom: 1px solid rgb(60, 112, 198);" data-linktype="2">【对线面试官】Java注解</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a href="https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247483823&idx=1&sn=cc887dc2c7e68a69e8d4d141c2ca9b5e&scene=21#wechat_redirect" style="overflow-wrap: break-word;font-weight: bold;color: rgb(60, 112, 198);border-bottom: 1px solid rgb(60, 112, 198);" data-linktype="2">【对线面试官】Java泛型</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a href="https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247483854&idx=1&sn=aa450a03ac0d6e8cf12cf13d4719ede3&scene=21#wechat_redirect" style="overflow-wrap: break-word;font-weight: bold;color: rgb(60, 112, 198);border-bottom: 1px solid rgb(60, 112, 198);" data-linktype="2">【对线面试官】 Java NIO</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a href="https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247483893&idx=1&sn=af51e626f2c2baec8cae4f4a15425957&scene=21#wechat_redirect" style="overflow-wrap: break-word;font-weight: bold;color: rgb(60, 112, 198);border-bottom: 1px solid rgb(60, 112, 198);" data-linktype="2">【对线面试官】Java反射 && 动态代理</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a href="https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247483918&idx=1&sn=ab8550bb284edcf7cf0c6d0b41e0c2f6&scene=21#wechat_redirect" style="overflow-wrap: break-word;font-weight: bold;color: rgb(60, 112, 198);border-bottom: 1px solid rgb(60, 112, 198);" data-linktype="2">【对线面试官】多线程基础</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a href="https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247483977&idx=1&sn=1a3aa3aec27073aa3b422bc41d7fbe2d&chksm=fdf0ea16ca8763005aff64834eeb7bef08bf4ee2d8febb7e8d4d8e5d1542336e13fac71e2881&scene=21&cur_album_id=1657204970858872832#wechat_redirect" style="overflow-wrap: break-word;font-weight: bold;color: rgb(60, 112, 198);border-bottom: 1px solid rgb(60, 112, 198);" data-linktype="2">【对线面试官】 CAS</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a href="https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247483980&idx=1&sn=c9b620834adb889ad8ccedb6afdcaed1&scene=21#wechat_redirect" style="overflow-wrap: break-word;font-weight: bold;color: rgb(60, 112, 198);border-bottom: 1px solid rgb(60, 112, 198);" data-linktype="2">【对线面试官】synchronized</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a href="https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247484035&idx=1&sn=ccaec352e192f1fd40020d9a984e9461&chksm=fdf0eadcca8763ca5c44bd19118fd00e843c163deb40cda444b3fc08430c57760db15eca1ea6&scene=21&cur_album_id=1657204970858872832#wechat_redirect" style="overflow-wrap: break-word;font-weight: bold;color: rgb(60, 112, 198);border-bottom: 1px solid rgb(60, 112, 198);" data-linktype="2">【对线面试官】AQS&&ReentrantLock</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a href="https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247484036&idx=1&sn=75e9e93a82a811e9c71b8127cf7ac677&chksm=fdf0eadbca8763cd7ab74757f9472d061c0244d2373a1ea85b1cbc833941441fdb1e91ead5b4&scene=21&cur_album_id=1657204970858872832#wechat_redirect" style="overflow-wrap: break-word;font-weight: bold;color: rgb(60, 112, 198);border-bottom: 1px solid rgb(60, 112, 198);" data-linktype="2">【对线面试官】线程池</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a href="https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247484118&idx=1&sn=9526a1dc0d42926dd9bcccfc55e6abc2&scene=21#wechat_redirect" style="overflow-wrap: break-word;font-weight: bold;color: rgb(60, 112, 198);border-bottom: 1px solid rgb(60, 112, 198);" data-linktype="2">【对线面试官】ThreadLocal</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a href="https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247484363&idx=1&sn=743dcdfb84f83cfc38882407f87c7c6d&chksm=fdf0eb94ca87628296d86d16769f25e10acd052bcd78f4a4608f4218e4948aff610b04a41f60&token=960279204&lang=zh_CN&scene=21#wechat_redirect" style="overflow-wrap: break-word;font-weight: bold;color: rgb(60, 112, 198);border-bottom: 1px solid rgb(60, 112, 198);" data-linktype="2">【对线面试官】CountDownLatch和CyclicBarrier</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a href="https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247484253&idx=1&sn=532db3941f47502582295cbb003f753d&chksm=fdf0eb02ca8762145c66b33bbb429399f1f0f27b31c22f7cf6c693c235e9a7cffdafb6ce2fdc&token=57394744&lang=zh_CN&scene=21#wechat_redirect" style="overflow-wrap: break-word;font-weight: bold;color: rgb(60, 112, 198);border-bottom: 1px solid rgb(60, 112, 198);" data-linktype="2">【对线面试官】List</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a href="https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247484280&idx=1&sn=87cfede653dabc26c909823a1dafd615&chksm=fdf0eb27ca876231095ff99f0b3e30acd7b2ee4cdc7ddb16da0bb6a3b02f531e27324059cf58&token=100834666&lang=zh_CN&scene=21#wechat_redirect" style="overflow-wrap: break-word;font-weight: bold;color: rgb(60, 112, 198);border-bottom: 1px solid rgb(60, 112, 198);" data-linktype="2">【对线面试官】Map</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a href="https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247484064&idx=1&sn=3a59514a8262ab61036fc89cf0b0a27e&chksm=fdf0eaffca8763e90002ce1daf365f717a4bda3e50878f65943f52d14bee78fc65e837ef32f9&token=664255414&lang=zh_CN&scene=21#wechat_redirect" style="overflow-wrap: break-word;font-weight: bold;color: rgb(60, 112, 198);border-bottom: 1px solid rgb(60, 112, 198);" data-linktype="2">【对线面试官】SpringMVC</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a href="https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247484147&idx=1&sn=ef282cd54351436fc33c47534b4c2ac1&chksm=fdf0eaacca8763ba9b6c69acdba6b0ae8801405c98295842a0b5d891fe80246d76a2a0470bea&token=1998524575&lang=zh_CN&scene=21#wechat_redirect" style="overflow-wrap: break-word;font-weight: bold;color: rgb(60, 112, 198);border-bottom: 1px solid rgb(60, 112, 198);" data-linktype="2">【对线面试官】Spring基础</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a href="https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247484187&idx=1&sn=8f831c40dca9b2a57fdfbd051e4eab44&chksm=fdf0eb44ca87625253ea831471110860d3f27e04488b2748ba90ad442b079aca3d6b95d31bbe&token=1998524575&lang=zh_CN&scene=21#wechat_redirect" style="overflow-wrap: break-word;font-weight: bold;color: rgb(60, 112, 198);border-bottom: 1px solid rgb(60, 112, 198);" data-linktype="2">【对线面试官】SpringBean生命周期</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a href="https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247484227&idx=1&sn=4a124a2dd5ef6ce062abdadf247b5cff&chksm=fdf0eb1cca87620a8679473dfdd50421eb6ccba2459a7cb59ae1652138f7bb508558f3d4649e&token=57394744&lang=zh_CN&scene=21#wechat_redirect" style="overflow-wrap: break-word;font-weight: bold;color: rgb(60, 112, 198);border-bottom: 1px solid rgb(60, 112, 198);" data-linktype="2">【对线面试官】Redis基础</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a href="https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247484323&idx=1&sn=c3306b3f9abb6f880e2672f169202a42&chksm=fdf0ebfcca8762eaf9b4873e79cd3445857b1f4476a854acdf9c19fb81e1a02146c65cff5078&token=610975656&lang=zh_CN&scene=21#wechat_redirect" style="overflow-wrap: break-word;font-weight: bold;color: rgb(60, 112, 198);border-bottom: 1px solid rgb(60, 112, 198);" data-linktype="2">【对线面试官】Redis持久化</a> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <a href="https://mp.weixin.qq.com/s?__biz=MzU4NzA3MTc5Mg==&mid=2247484387&idx=1&sn=5bb2ba58776e65f53b091a4bcdb73755&chksm=fdf0ebbcca8762aadc359066ecd70274fa23ee846f9ba9114017402dcbed415f25f97d3020a6&token=1131755397&lang=zh_CN&scene=21#wechat_redirect" style="overflow-wrap: break-word;font-weight: bold;color: rgb(60, 112, 198);border-bottom: 1px solid rgb(60, 112, 198);" data-linktype="2">【对线面试官】Kafka基础</a> </section></li> </ul> </section> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="padding-right: 10px;padding-left: 10px;overflow-wrap: break-word;text-align: left;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;line-height: 1.6;letter-spacing: 0.034em;color: rgb(63, 63, 63);font-size: 16px;"> <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="1.7786666666666666" src="/upload/6703775451472e61511d0205e135505.jpg" data-type="jpeg" data-w="750" style="letter-spacing: 0.034em;display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> </figure> <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="1.7786666666666666" src="/upload/fba87be16bedf5df449e373cae8b8f72.jpg" data-type="jpeg" data-w="750" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> </figure> <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="1.7786666666666666" src="/upload/f8cbb0c4c9122633309bb90348cee39c.jpg" data-type="jpeg" data-w="750" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> </figure> <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="1.7786666666666666" src="/upload/7f2840dcca0b23bb8ef828a5bf427885.jpg" data-type="jpeg" data-w="750" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> </figure> <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="1.7786666666666666" src="/upload/8639bc1a69f12b8e425d8a328faa97a1.jpg" data-type="jpeg" data-w="750" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> </figure> <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="1.7786666666666666" src="/upload/491ffbda879d7a19f5fc491cb61e94ff.jpg" data-type="jpeg" data-w="750" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> </figure> <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="1.7786666666666666" src="/upload/4528e46bb597cbe885983365a094cd31.jpg" data-type="jpeg" data-w="750" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> </figure> <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="1.7786666666666666" src="/upload/c9666141cdadfcd4f2d0ce61bd7f0fb3.jpg" data-type="jpeg" data-w="750" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> </figure> <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="1.7786666666666666" src="/upload/7f07156b0229ee507c7ea2d7a1596f2a.jpg" data-type="jpeg" data-w="750" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> </figure> <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="1.7786666666666666" src="/upload/b6aacc54d57308140e41337907282483.jpg" data-type="jpeg" data-w="750" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> </figure> <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="1.7786666666666666" src="/upload/6318687ea234b20a4710da585052fcd6.jpg" data-type="jpeg" data-w="750" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> </figure> <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="1.7786666666666666" src="/upload/b2e0698a0a7d0fcdbaef2ab820d686a1.jpg" data-type="jpeg" data-w="750" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> </figure> <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="1.7786666666666666" src="/upload/5837665542937a873ce2570d111e693b.jpg" data-type="jpeg" data-w="750" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> </figure> <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="1.7786666666666666" src="/upload/ccddefadb21082431e2dcc66cfc558a9.jpg" data-type="jpeg" data-w="750" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> </figure> <p style="text-align: center;"><img class="rich_pages" data-galleryid="" data-ratio="0.571992110453649" data-s="300,640" src="/upload/f901fe4e45c77b83f0ac80191e6774da.png" data-type="png" data-w="2028" style=""></p> </section> <section class="mp_profile_iframe_wrp"> <mpprofile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-id="MzU4NzA3MTc5Mg==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/E44aHibktsKbNnU5S5B6m5yVtNbmfEUsMmf4eqOBEsXzMILa9eAZvBR4mntYwkkp59nicicN1soBWsduGrxLFVzWQ/0?wx_fmt=png" data-nickname="面试造火箭" data-alias="" data-signature="入职拧螺丝"></mpprofile> </section> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);font-size: 16px;caret-color: rgb(0, 0, 0);color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;text-align: left;line-height: 26px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">文章以纯面试的角度去讲解,所以有很多的细节是未铺垫的。</strong><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);font-size: 16px;caret-color: rgb(0, 0, 0);color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;text-align: left;line-height: 26px;box-sizing: border-box !important;overflow-wrap: break-word !important;">鉴于很多同学反馈没看懂【<strong style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">对线面试官</strong>】系列,基础相关的知识我确实写过文章讲解过啦,但有的同学就是不爱去翻。<span style="max-width: 100%;letter-spacing: 0.544px;color: rgb(51, 51, 51);box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);font-size: 16px;caret-color: rgb(0, 0, 0);color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;text-align: left;line-height: 26px;box-sizing: border-box !important;overflow-wrap: break-word !important;">我把这些<strong style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">上传到网盘</strong>,你们有需要直接下载就好了。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);font-size: 16px;caret-color: rgb(0, 0, 0);color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;text-align: left;line-height: 26px;box-sizing: border-box !important;overflow-wrap: break-word !important;">1. 消息队列的和Kafka的<span style="max-width: 100%;letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;">基础讲解都已经写过啦</span></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);font-size: 16px;caret-color: rgb(0, 0, 0);color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;text-align: left;line-height: 26px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;">2. Kafka用到的Zookeeper也已经写过了</span></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);font-size: 16px;caret-color: rgb(0, 0, 0);color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;text-align: left;line-height: 26px;box-sizing: border-box !important;overflow-wrap: break-word !important;">3. 有兴趣的同学也可以翻下我大数据相关的文章<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);caret-color: rgb(0, 0, 0);color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 14px;text-align: left;display: flex;flex-direction: column;justify-content: center;align-items: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <img data-ratio="0.3302387267904509" data-type="jpeg" data-w="1508" src="/upload/e05acdfb7762b54ec9b09e2738219d94.jpg" style="margin-top: 10px;margin-right: auto;margin-left: auto;display: block;box-shadow: rgba(170, 170, 170, 0.48) 0px 0px 6px 0px;border-radius: 4px;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 677px !important;"> </figure> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);caret-color: rgb(0, 0, 0);color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 14px;text-align: left;display: flex;flex-direction: column;justify-content: center;align-items: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <strong style="max-width: 100%;text-align: center;font-size: 16px;letter-spacing: 0px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="color: rgb(255, 104, 39);letter-spacing: 0px;">怎样偷偷努力 惊艳所有人?</span><br></strong> </figure> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);caret-color: rgb(0, 0, 0);color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 14px;text-align: left;display: flex;flex-direction: column;justify-content: center;align-items: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section class="mp_profile_iframe_wrp"> <mpprofile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-id="MzU4NzA3MTc5Mg==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/E44aHibktsKbNnU5S5B6m5yVtNbmfEUsMmf4eqOBEsXzMILa9eAZvBR4mntYwkkp59nicicN1soBWsduGrxLFVzWQ/0?wx_fmt=png" data-nickname="面试造火箭" data-alias="" data-signature="入职拧螺丝"></mpprofile> </section> <strong style="max-width: 100%;text-align: center;font-size: 16px;letter-spacing: 0px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;">点击小卡片关注【</span><span style="max-width: 100%;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;color: rgb(255, 104, 39);box-sizing: border-box !important;overflow-wrap: break-word !important;">面试造火箭</span><span style="letter-spacing: 0px;max-width: 100%;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;">】</span><br></strong> </figure> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);caret-color: rgb(0, 0, 0);color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 14px;text-align: left;display: flex;flex-direction: column;justify-content: center;align-items: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <strong style="max-width: 100%;text-align: center;font-size: 16px;letter-spacing: 0px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;letter-spacing: 0px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;">关注后回复「</span><strong style="max-width: 100%;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;letter-spacing: 0px;color: rgb(255, 104, 39);box-sizing: border-box !important;overflow-wrap: break-word !important;">888</span></strong><span style="max-width: 100%;letter-spacing: 0px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;">」还可获取网盘地址哟!</span></strong> </figure>
作者:微信小助手
<p style="max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(62, 62, 62);font-size: 15px;text-size-adjust: auto;word-spacing: 2px;text-align: center;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;letter-spacing: 0.544px;color: rgb(136, 136, 136);font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;">点击蓝色“</span><span style="max-width: 100%;letter-spacing: 0.544px;font-size: 14px;color: rgb(0, 128, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;">架构文摘</span><span style="max-width: 100%;letter-spacing: 0.544px;color: rgb(136, 136, 136);font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;">”关注我哟</span></p> <p style="margin-bottom: 10px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(62, 62, 62);font-size: 15px;text-size-adjust: auto;word-spacing: 2px;text-align: center;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 14px;color: rgb(136, 136, 136);box-sizing: border-box !important;overflow-wrap: break-word !important;">加个“</span><span style="max-width: 100%;color: rgb(0, 128, 255);font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;">星标</span><span style="max-width: 100%;font-size: 14px;color: rgb(136, 136, 136);box-sizing: border-box !important;overflow-wrap: break-word !important;">”,每天上午 09:25,干货推送!</span></p> <p style="max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(62, 62, 62);font-size: 14px;text-align: right;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><img data-backh="36" data-backw="578" data-ratio="0.0625" data-s="300,640" src="/upload/8c292e55ba5a23cb6ebc11f2a2c4fece.jpg" data-type="jpeg" data-w="640" style="font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;widows: 1;word-spacing: 2px;color: rgb(136, 136, 136);box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 677px !important;" width="100%"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p> <p style="max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: right;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p> <p style="max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="color: rgb(136, 136, 136);font-size: 10px;letter-spacing: 0.544px;font-family: Optima-Regular, PingFangTC-light;">作者:</span><span style="color: rgb(136, 136, 136);font-size: 10px;letter-spacing: 0.544px;font-family: Optima-Regular, PingFangTC-light;">王啸 tr1912</span></p> <p style="max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(178, 178, 178);font-family: Optima-Regular, PingFangTC-light;font-size: 13px;letter-spacing: 0.544px;text-align: left;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(136, 136, 136);font-size: 10px;letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;">blog.csdn.net/tr1912/article/details/81668423</span></span></p> <h2 style="margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;font-size: 20px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(255, 140, 0);line-height: 1.35;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: Menlo, Monaco, "Source Code Pro", Consolas, Inconsolata, "Ubuntu Mono", "DejaVu Sans Mono", "Courier New", "Droid Sans Mono", "Hiragino Sans GB", 微软雅黑, monospace !important;"><strong><span style="max-width: 100%;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">一、MySQL锁类型和加锁分析</span></strong></h2> <h3 style="margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;font-size: 18px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(255, 140, 0);line-height: 1.35;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: Menlo, Monaco, "Source Code Pro", Consolas, Inconsolata, "Ubuntu Mono", "DejaVu Sans Mono", "Courier New", "Droid Sans Mono", "Hiragino Sans GB", 微软雅黑, monospace !important;">锁类型介绍:</h3> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">MySQL 有三种锁的级别:页级、表级、行级。</p> <ul class="list-paddingleft-2" style="padding-left: 20px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);list-style-position: initial;list-style-image: initial;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;margin-top: 2px !important;overflow-wrap: break-word !important;list-style-type: square !important;"> <li style="max-width: 100%;margin-top: 2px !important;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="margin-bottom: 15px;max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;">表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高, 并发度最低。</p></li> <li style="max-width: 100%;margin-top: 2px !important;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="margin-bottom: 15px;max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;">行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低, 并发度也最高。</p></li> <li style="max-width: 100%;margin-top: 2px !important;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="margin-bottom: 15px;max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;">页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般</p></li> </ul> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">算法:</p> <ul class="list-paddingleft-2" style="padding-left: 20px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);list-style-position: initial;list-style-image: initial;color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;margin-top: 2px !important;overflow-wrap: break-word !important;list-style-type: square !important;"> <li style="max-width: 100%;margin-top: 2px !important;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="margin-bottom: 15px;max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;">next KeyLocks 锁,同时锁住记录 (数据),并且锁住记录前面的 Gap</p></li> <li style="max-width: 100%;margin-top: 2px !important;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="margin-bottom: 15px;max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;">Gap 锁,不锁记录,仅仅记录前面的 Gap</p></li> <li style="max-width: 100%;margin-top: 2px !important;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="margin-bottom: 15px;max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;">Recordlock 锁(锁数据,不锁 Gap)</p></li> <li style="max-width: 100%;margin-top: 2px !important;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="margin-bottom: 15px;max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;">所以其实 Next-KeyLocks=Gap 锁 + Recordlock 锁</p></li> </ul> <h2 style="margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;font-size: 20px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(255, 140, 0);line-height: 1.35;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: Menlo, Monaco, "Source Code Pro", Consolas, Inconsolata, "Ubuntu Mono", "DejaVu Sans Mono", "Courier New", "Droid Sans Mono", "Hiragino Sans GB", 微软雅黑, monospace !important;"><strong><span style="max-width: 100%;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">二、死锁产生原因和示例</span></strong></h2> <h3 style="margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;font-size: 18px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(255, 140, 0);line-height: 1.35;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: Menlo, Monaco, "Source Code Pro", Consolas, Inconsolata, "Ubuntu Mono", "DejaVu Sans Mono", "Courier New", "Droid Sans Mono", "Hiragino Sans GB", 微软雅黑, monospace !important;">1、产生原因:</h3> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">所谓死锁<code style="padding-right: 5px;padding-left: 5px;max-width: 100%;font-family: Courier, "Courier New", monospace;background-color: bisque;box-sizing: border-box !important;overflow-wrap: break-word !important;"><DeadLock></code>:是指两个或两个以上的进程在执行过程中, 因争夺资源而造成的一种互相等待的现象, 若无外力作用,它们都将无法推进下去. 此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。表级锁不会产生死锁. 所以解决死锁主要还是针对于最常用的 InnoDB。</p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">死锁的关键在于:两个 (或以上) 的 Session 加锁的顺序不一致。</p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">那么对应的解决死锁问题的关键就是:让不同的 session 加锁有次序</p> <h3 style="margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;font-size: 18px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(255, 140, 0);line-height: 1.35;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: Menlo, Monaco, "Source Code Pro", Consolas, Inconsolata, "Ubuntu Mono", "DejaVu Sans Mono", "Courier New", "Droid Sans Mono", "Hiragino Sans GB", 微软雅黑, monospace !important;">2、产生示例:</h3> <h4 style="margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;font-size: 15px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(255, 140, 0);line-height: 1.35;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: Menlo, Monaco, "Source Code Pro", Consolas, Inconsolata, "Ubuntu Mono", "DejaVu Sans Mono", "Courier New", "Droid Sans Mono", "Hiragino Sans GB", 微软雅黑, monospace !important;">案例一</h4> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">需求:将投资的钱拆成几份随机分配给借款人。</p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">起初业务程序思路是这样的:</p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">投资人投资后,将金额随机分为几份,然后随机从借款人表里面选几个,然后通过一条条<code style="padding-right: 5px;padding-left: 5px;max-width: 100%;font-family: Courier, "Courier New", monospace;background-color: bisque;box-sizing: border-box !important;overflow-wrap: break-word !important;">select for update</code> 去更新借款人表里面的余额等。</p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">例如两个用户同时投资,A 用户金额随机分为 2 份,分给借款人 1,2</p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">B 用户金额随机分为 2 份,分给借款人 2,1</p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">由于加锁的顺序不一样,死锁当然很快就出现了。<span style="letter-spacing: 0.544px;"></span></p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">对于这个问题的改进很简单,直接把所有分配到的借款人直接一次锁住就行了。</p> <pre style="padding: 0.5em;max-width: 100%;letter-spacing: 0.544px;font-family: Courier, "Courier New", monospace;background: rgb(45, 45, 45);border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);overflow-x: auto;color: rgb(204, 204, 204);font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;"><code style="max-width: 100%;overflow-wrap: normal;font-family: Courier, "Courier New", monospace;display: inline;overflow: initial;line-height: inherit;border-width: 0px;border-style: initial;border-color: initial;font-size: 13.5px;box-sizing: border-box !important;">Select * <span style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">from xxx where id <span style="max-width: 100%;color: rgb(102, 153, 204);font-weight: 700;box-sizing: border-box !important;overflow-wrap: break-word !important;">in</span> <span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">(xx,xx,xx)</span> <span style="max-width: 100%;font-weight: 700;color: rgb(204, 153, 204);box-sizing: border-box !important;overflow-wrap: break-word !important;">for</span> update<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></code></pre> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">在 in 里面的列表值 mysql 是会自动从小到大排序,加锁也是一条条从小到大加的锁</p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">例如(以下会话 id 为主键):</p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Session1:</strong></p> <pre style="padding: 0.5em;max-width: 100%;letter-spacing: 0.544px;font-family: Courier, "Courier New", monospace;background: rgb(45, 45, 45);border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);overflow-x: auto;color: rgb(204, 204, 204);font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;"><code style="max-width: 100%;overflow-wrap: normal;font-family: Courier, "Courier New", monospace;display: inline;overflow: initial;line-height: inherit;border-width: 0px;border-style: initial;border-color: initial;font-size: 13.5px;box-sizing: border-box !important;">mysql> select * <span style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">from t3 where id <span style="max-width: 100%;color: rgb(102, 153, 204);font-weight: 700;box-sizing: border-box !important;overflow-wrap: break-word !important;">in</span> <span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">(<span style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">8</span>,<span style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">9</span>)</span> <span style="max-width: 100%;font-weight: 700;color: rgb(204, 153, 204);box-sizing: border-box !important;overflow-wrap: break-word !important;">for</span> update</span>;<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">+----+--------+------+---------------------+<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">| id | course | name | ctime |<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">+----+--------+------+---------------------+<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">| <span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">8</span> | WA | f | <span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">2016</span>-<span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">03</span>-<span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">02</span> <span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">11</span>:<span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">36</span>:<span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">30</span> |<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">| <span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">9</span> | JX | f | <span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">2016</span>-<span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">03</span>-<span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">01</span> <span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">11</span>:<span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">36</span>:<span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">30</span> |<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">+----+--------+------+---------------------+<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">rows in <span style="max-width: 100%;color: rgb(102, 153, 204);font-weight: 700;box-sizing: border-box !important;overflow-wrap: break-word !important;">set</span> <span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">(<span style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">0.04</span> sec)</span><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></code></pre> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Session2:</strong></p> <pre style="padding: 0.5em;max-width: 100%;letter-spacing: 0.544px;font-family: Courier, "Courier New", monospace;background: rgb(45, 45, 45);border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);overflow-x: auto;color: rgb(204, 204, 204);font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;"><code style="max-width: 100%;overflow-wrap: normal;font-family: Courier, "Courier New", monospace;display: inline;overflow: initial;line-height: inherit;border-width: 0px;border-style: initial;border-color: initial;font-size: 13.5px;box-sizing: border-box !important;">select * <span style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">from t3 where id <span style="max-width: 100%;color: rgb(102, 153, 204);font-weight: 700;box-sizing: border-box !important;overflow-wrap: break-word !important;">in</span> <span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">(<span style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">10</span>,<span style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">8</span>,<span style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">5</span>)</span> <span style="max-width: 100%;font-weight: 700;color: rgb(204, 153, 204);box-sizing: border-box !important;overflow-wrap: break-word !important;">for</span> update</span>;<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></code></pre> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">锁等待中……</p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">其实这个时候 id=10 这条记录没有被锁住的,但 id=5 的记录已经被锁住了,锁的等待在 id=8 的这里 不信请看</p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Session3:</strong></p> <pre style="padding: 0.5em;max-width: 100%;letter-spacing: 0.544px;font-family: Courier, "Courier New", monospace;background: rgb(45, 45, 45);border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);overflow-x: auto;color: rgb(204, 204, 204);font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;"><code style="max-width: 100%;overflow-wrap: normal;font-family: Courier, "Courier New", monospace;display: inline;overflow: initial;line-height: inherit;border-width: 0px;border-style: initial;border-color: initial;font-size: 13.5px;box-sizing: border-box !important;">mysql> select * from t3 where id=<span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">5</span> <span style="max-width: 100%;font-weight: 700;color: rgb(204, 153, 204);box-sizing: border-box !important;overflow-wrap: break-word !important;">for</span> update;<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></code></pre> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">锁等待中</p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Session4:</strong></p> <pre style="padding: 0.5em;max-width: 100%;letter-spacing: 0.544px;font-family: Courier, "Courier New", monospace;background: rgb(45, 45, 45);border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);overflow-x: auto;color: rgb(204, 204, 204);font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;"><code style="max-width: 100%;overflow-wrap: normal;font-family: Courier, "Courier New", monospace;display: inline;overflow: initial;line-height: inherit;border-width: 0px;border-style: initial;border-color: initial;font-size: 13.5px;box-sizing: border-box !important;">mysql> select * from t3 where id=<span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">10</span> <span style="max-width: 100%;font-weight: 700;color: rgb(204, 153, 204);box-sizing: border-box !important;overflow-wrap: break-word !important;">for</span> update;<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">+----+--------+------+---------------------+<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">| id | course | name | ctime |<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">+----+--------+------+---------------------+<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">| <span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">10</span> | JB | g | <span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">2016</span>-<span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">03</span>-<span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">10</span> <span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">11</span>:<span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">45</span>:<span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">05</span> |<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">+----+--------+------+---------------------+<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">row in <span style="max-width: 100%;color: rgb(102, 153, 204);font-weight: 700;box-sizing: border-box !important;overflow-wrap: break-word !important;">set</span> <span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">(<span style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">0.00</span> sec)</span><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></code></pre> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">在其它 session 中 id=5 是加不了锁的,但是 id=10 是可以加上锁的。</p> <h4 style="margin-top: 2rem;margin-bottom: 0.5rem;font-weight: 700;font-size: 15px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(255, 140, 0);line-height: 1.35;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;font-family: Menlo, Monaco, "Source Code Pro", Consolas, Inconsolata, "Ubuntu Mono", "DejaVu Sans Mono", "Courier New", "Droid Sans Mono", "Hiragino Sans GB", 微软雅黑, monospace !important;">案例二</h4> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">在开发中,经常会做这类的判断需求:根据字段值查询(有索引),如果不存在,则插入;否则更新。</p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">以 id 为主键为例,目前还没有 id=22 的行</p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Session1:</strong></p> <pre style="padding: 0.5em;max-width: 100%;letter-spacing: 0.544px;font-family: Courier, "Courier New", monospace;background: rgb(45, 45, 45);border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);overflow-x: auto;color: rgb(204, 204, 204);font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;"><code style="max-width: 100%;overflow-wrap: normal;font-family: Courier, "Courier New", monospace;display: inline;overflow: initial;line-height: inherit;border-width: 0px;border-style: initial;border-color: initial;font-size: 13.5px;box-sizing: border-box !important;">select * from t3 where id=<span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">22</span> <span style="max-width: 100%;font-weight: 700;color: rgb(204, 153, 204);box-sizing: border-box !important;overflow-wrap: break-word !important;">for</span> update;<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">Empty <span style="max-width: 100%;color: rgb(102, 153, 204);font-weight: 700;box-sizing: border-box !important;overflow-wrap: break-word !important;">set</span> <span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">(<span style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">0.00</span> sec)</span><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></code></pre> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">session2:</strong></p> <pre style="padding: 0.5em;max-width: 100%;letter-spacing: 0.544px;font-family: Courier, "Courier New", monospace;background: rgb(45, 45, 45);border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);overflow-x: auto;color: rgb(204, 204, 204);font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;"><code style="max-width: 100%;overflow-wrap: normal;font-family: Courier, "Courier New", monospace;display: inline;overflow: initial;line-height: inherit;border-width: 0px;border-style: initial;border-color: initial;font-size: 13.5px;box-sizing: border-box !important;">select * from t3 where id=<span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">23</span> <span style="max-width: 100%;font-weight: 700;color: rgb(204, 153, 204);box-sizing: border-box !important;overflow-wrap: break-word !important;">for</span> update;<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">Empty <span style="max-width: 100%;color: rgb(102, 153, 204);font-weight: 700;box-sizing: border-box !important;overflow-wrap: break-word !important;">set</span> <span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">(<span style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">0.00</span> sec)</span><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></code></pre> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Session1:</strong></p> <pre style="padding: 0.5em;max-width: 100%;letter-spacing: 0.544px;font-family: Courier, "Courier New", monospace;background: rgb(45, 45, 45);border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);overflow-x: auto;color: rgb(204, 204, 204);font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;"><code style="max-width: 100%;overflow-wrap: normal;font-family: Courier, "Courier New", monospace;display: inline;overflow: initial;line-height: inherit;border-width: 0px;border-style: initial;border-color: initial;font-size: 13.5px;box-sizing: border-box !important;"><span style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">insert into t3 <span style="max-width: 100%;color: rgb(102, 153, 204);font-weight: 700;box-sizing: border-box !important;overflow-wrap: break-word !important;">values</span><span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">(<span style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">22</span>,<span style="max-width: 100%;color: rgb(153, 204, 153);box-sizing: border-box !important;overflow-wrap: break-word !important;">'ac'</span>,<span style="max-width: 100%;color: rgb(153, 204, 153);box-sizing: border-box !important;overflow-wrap: break-word !important;">'a'</span>,now()</span>)</span>;<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></code></pre> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">锁等待中……</p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Session2:</strong></p> <pre style="padding: 0.5em;max-width: 100%;letter-spacing: 0.544px;font-family: Courier, "Courier New", monospace;background: rgb(45, 45, 45);border-width: 1px;border-style: solid;border-color: rgb(221, 221, 221);overflow-x: auto;color: rgb(204, 204, 204);font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;"><code style="max-width: 100%;overflow-wrap: normal;font-family: Courier, "Courier New", monospace;display: inline;overflow: initial;line-height: inherit;border-width: 0px;border-style: initial;border-color: initial;font-size: 13.5px;box-sizing: border-box !important;"><span style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">insert into t3 <span style="max-width: 100%;color: rgb(102, 153, 204);font-weight: 700;box-sizing: border-box !important;overflow-wrap: break-word !important;">values</span><span style="max-width: 100%;color: rgb(249, 145, 87);box-sizing: border-box !important;overflow-wrap: break-word !important;">(<span style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">23</span>,<span style="max-width: 100%;color: rgb(153, 204, 153);box-sizing: border-box !important;overflow-wrap: break-word !important;">'bc'</span>,<span style="max-width: 100%;color: rgb(153, 204, 153);box-sizing: border-box !important;overflow-wrap: break-word !important;">'b'</span>,now()</span>)</span>;<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></code></pre> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;"><code style="padding-right: 5px;padding-left: 5px;max-width: 100%;font-family: Courier, "Courier New", monospace;background-color: bisque;box-sizing: border-box !important;overflow-wrap: break-word !important;">ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction</code></p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">当对存在的行进行锁的时候 (主键),mysql 就只有行锁。</p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">当对未存在的行进行锁的时候 (即使条件为主键),mysql 是会锁住一段范围(有 gap 锁)</p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">锁住的范围为:</strong></p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(80, 97, 109);font-family: Helvetica, Arial, sans-serif;font-size: 15px;text-align: start;box-sizing: border-box !important;overflow-wrap: break-word !important;">(无穷小或小于表中锁住 id 的最大值,无穷大或大于表中锁住 id 的最小值)</p> <p style="margin-top: 15px;margin-bottom: 15px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);co
作者:微信小助手
<p style="max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(62, 62, 62);font-size: 15px;text-size-adjust: auto;word-spacing: 2px;text-align: center;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;letter-spacing: 0.544px;color: rgb(136, 136, 136);font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;">点击蓝色“</span><span style="max-width: 100%;letter-spacing: 0.544px;font-size: 14px;color: rgb(0, 128, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;">架构文摘</span><span style="max-width: 100%;letter-spacing: 0.544px;color: rgb(136, 136, 136);font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;">”关注我哟</span></p> <p style="margin-bottom: 10px;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(62, 62, 62);font-size: 15px;text-size-adjust: auto;word-spacing: 2px;text-align: center;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 14px;color: rgb(136, 136, 136);box-sizing: border-box !important;overflow-wrap: break-word !important;">加个“</span><span style="max-width: 100%;color: rgb(0, 128, 255);font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;">星标</span><span style="max-width: 100%;font-size: 14px;color: rgb(136, 136, 136);box-sizing: border-box !important;overflow-wrap: break-word !important;">”,每天上午 09:25,干货推送!</span></p> <p style="max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(62, 62, 62);font-size: 14px;text-align: right;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><img data-backh="36" data-backw="578" data-ratio="0.0625" data-s="300,640" src="/upload/8c292e55ba5a23cb6ebc11f2a2c4fece.jpg" data-type="jpeg" data-w="640" style="font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;widows: 1;word-spacing: 2px;color: rgb(136, 136, 136);box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 677px !important;" width="100%"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p> <p style="max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: right;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p> <p style="max-width: 100%;min-height: 1em;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: left;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="letter-spacing: 0.544px;color: rgb(136, 136, 136);font-family: Optima-Regular, PingFangTC-light;font-size: 10px;">作者:</span><span style="letter-spacing: 0.544px;color: rgb(136, 136, 136);font-family: Optima-Regular, PingFangTC-light;font-size: 10px;">琴水玉</span></p> <section style="max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);min-height: 1em;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <span style="max-width: 100%;letter-spacing: 0.544px;color: rgb(136, 136, 136);font-family: Optima-Regular, PingFangTC-light;font-size: 10px;text-align: left;box-sizing: border-box !important;overflow-wrap: break-word !important;">原文:https://cnblogs.com/lovesqcc/p/4319594.html</span> </section> <section style="max-width: 100%;letter-spacing: 0.544px;white-space: normal;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> </section> <section style="max-width: 100%;letter-spacing: 0.544px;white-space: normal;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <p style="text-align: center;"><img class="rich_pages" data-galleryid="" data-ratio="0.40106951871657753" data-s="300,640" src="/upload/25b9a56c5d8cfb9a3c6a15e3c222d128.png" data-type="png" data-w="748" style=""></p> </section> <section style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);min-height: 1em;color: rgb(0, 0, 0);font-size: 16px;text-align: left;line-height: 26px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> 在程序中打错误日志的主要目标是为更好地排查问题和解决问题提供重要线索和指导。但是在实际中打的错误日志内容和格式变化多样,错误提示上可能残缺不全、没有相关背景、不明其义,使得排查解决问题成为非常不方便或者耗时的操作。而实际上,如果编程的时候稍加用心,就会减少排查问题的很多无用功。 </section> <section style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);min-height: 1em;color: rgb(0, 0, 0);font-size: 16px;text-align: left;line-height: 26px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> 在阐述如何编写有效的错误日志之前,了解错误是怎么产生的,非常重要。 </section> <section style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);min-height: 1em;color: rgb(0, 0, 0);font-size: 16px;text-align: left;line-height: 26px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <strong style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">错误是如何炼成的</strong> </section> <section style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);min-height: 1em;color: rgb(0, 0, 0);font-size: 16px;text-align: left;line-height: 26px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzI3ODcxMzQzMw==&mid=2247524678&idx=3&sn=a153fd4fae16c357d55414e067d7bf25&chksm=eb50e470dc276d6676c923b597cbd28cf29e7a31393f1f03afedaf22f6aaf9e0e5517b9bdb32&scene=21#wechat_redirect" textvalue="对于当前系统来说, 错误的产生由三个地方引入:1.上层系统引入的非法参数。对于非法参数引入的错误, 可以通过参数校验和前置条件校验来截获错误;2.与下层系统交互产生的错误。与下层交互产生的错误, 有两种:a.下层系统处理成功了,但是通信出错了, 这样会导致子系统之间的数据不一致;对于这种情况, 可以采用超时补偿机制,预先将任务记录下来,通过定时任务在后续将数据订正过来。" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">对于当前系统来说, 错误的产生由三个地方引入:</span></a> </section> <section style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);min-height: 1em;color: rgb(0, 0, 0);font-size: 16px;text-align: left;line-height: 26px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzI3ODcxMzQzMw==&mid=2247524678&idx=3&sn=a153fd4fae16c357d55414e067d7bf25&chksm=eb50e470dc276d6676c923b597cbd28cf29e7a31393f1f03afedaf22f6aaf9e0e5517b9bdb32&scene=21#wechat_redirect" textvalue="对于当前系统来说, 错误的产生由三个地方引入:1.上层系统引入的非法参数。对于非法参数引入的错误, 可以通过参数校验和前置条件校验来截获错误;2.与下层系统交互产生的错误。与下层交互产生的错误, 有两种:a.下层系统处理成功了,但是通信出错了, 这样会导致子系统之间的数据不一致;对于这种情况, 可以采用超时补偿机制,预先将任务记录下来,通过定时任务在后续将数据订正过来。" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">1.上层系统引入的非法参数。对于非法参数引入的错误, 可以通过参数校验和前置条件校验来截获错误;</span></a> </section> <section style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);min-height: 1em;color: rgb(0, 0, 0);font-size: 16px;text-align: left;line-height: 26px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzI3ODcxMzQzMw==&mid=2247524678&idx=3&sn=a153fd4fae16c357d55414e067d7bf25&chksm=eb50e470dc276d6676c923b597cbd28cf29e7a31393f1f03afedaf22f6aaf9e0e5517b9bdb32&scene=21#wechat_redirect" textvalue="对于当前系统来说, 错误的产生由三个地方引入:1.上层系统引入的非法参数。对于非法参数引入的错误, 可以通过参数校验和前置条件校验来截获错误;2.与下层系统交互产生的错误。与下层交互产生的错误, 有两种:a.下层系统处理成功了,但是通信出错了, 这样会导致子系统之间的数据不一致;对于这种情况, 可以采用超时补偿机制,预先将任务记录下来,通过定时任务在后续将数据订正过来。" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">2.与下层系统交互产生的错误。与下层交互产生的错误, 有两种:</span></a> </section> <section style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);min-height: 1em;color: rgb(0, 0, 0);font-size: 16px;text-align: left;line-height: 26px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzI3ODcxMzQzMw==&mid=2247524678&idx=3&sn=a153fd4fae16c357d55414e067d7bf25&chksm=eb50e470dc276d6676c923b597cbd28cf29e7a31393f1f03afedaf22f6aaf9e0e5517b9bdb32&scene=21#wechat_redirect" textvalue="对于当前系统来说, 错误的产生由三个地方引入:1.上层系统引入的非法参数。对于非法参数引入的错误, 可以通过参数校验和前置条件校验来截获错误;2.与下层系统交互产生的错误。与下层交互产生的错误, 有两种:a.下层系统处理成功了,但是通信出错了, 这样会导致子系统之间的数据不一致;对于这种情况, 可以采用超时补偿机制,预先将任务记录下来,通过定时任务在后续将数据订正过来。" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">a.下层系统处理成功了,但是通信出错了, 这样会导致子系统之间的数据不一致;</span></a> </section> <section style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);min-height: 1em;color: rgb(0, 0, 0);font-size: 16px;text-align: left;line-height: 26px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzI3ODcxMzQzMw==&mid=2247524678&idx=3&sn=a153fd4fae16c357d55414e067d7bf25&chksm=eb50e470dc276d6676c923b597cbd28cf29e7a31393f1f03afedaf22f6aaf9e0e5517b9bdb32&scene=21#wechat_redirect" textvalue="对于当前系统来说, 错误的产生由三个地方引入:1.上层系统引入的非法参数。对于非法参数引入的错误, 可以通过参数校验和前置条件校验来截获错误;2.与下层系统交互产生的错误。与下层交互产生的错误, 有两种:a.下层系统处理成功了,但是通信出错了, 这样会导致子系统之间的数据不一致;对于这种情况, 可以采用超时补偿机制,预先将任务记录下来,通过定时任务在后续将数据订正过来。" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">对于这种情况, 可以采用超时补偿机制,预先将任务记录下来,通过定时任务在后续将数据订正过来。</span></a> </section> <section style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);min-height: 1em;color: rgb(0, 0, 0);font-size: 16px;text-align: left;line-height: 26px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <strong style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">更好的设计方案 ?</strong> </section> <section style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);min-height: 1em;color: rgb(0, 0, 0);font-size: 16px;text-align: left;line-height: 26px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> b.通信成功了,但是下层处理出错了。 </section> <section style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);min-height: 1em;color: rgb(0, 0, 0);font-size: 16px;text-align: left;line-height: 26px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> 对于这种情况, 需要与下层开发人员沟通, 协调子系统之间的交互; </section> <section style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);min-height: 1em;color: rgb(0, 0, 0);font-size: 16px;text-align: left;line-height: 26px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> 需要根据下层返回的错误码和错误描述做适当的处理或给予合理的提示信息。 </section> <section style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);min-height: 1em;color: rgb(0, 0, 0);font-size: 16px;text-align: left;line-height: 26px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> 无论哪一种情况, 都要假设下层系统可靠性一般, 做好出错的设计考虑。 </section> <section style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);min-height: 1em;color: rgb(0, 0, 0);font-size: 16px;text-align: left;line-height: 26px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> 3.本层系统处理出错。 </section> <section style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);min-height: 1em;color: rgb(0, 0, 0);font-size: 16px;text-align: left;line-height: 26px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> 本层系统产生错误的原因: </section> <section style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);min-height: 1em;color: rgb(0, 0, 0);font-size: 16px;text-align: left;line-height: 26px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <strong style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">原因一:疏忽导致。</strong> </section> <section style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);min-height: 1em;color: rgb(0, 0, 0);font-size: 16px;text-align: left;line-height: 26px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;box-sizing: border-box !important;overflow-wrap: break-word !important;"> 疏忽是指程序员能力完全可避免此类错误但实际上没做到。比如将 && 敲成了 & , == 敲成了 = ;边界错误, 复合逻辑判断错误等。疏忽要么是程序员注意力不够集中, 比如处于疲倦状态、加班通宵、边开会边写程序;要么是
作者:微信小助手
<p data-lake-id="f47942fff38c686ed626a530b6d84219" style="text-align: center;font-size: 15px;color: rgb(64, 64, 64);line-height: 1.74;letter-spacing: 0.008em;outline-style: none;overflow-wrap: break-word;" data-mpa-powered-by="yiban.io"><span data-mce-style="font-size: 10px" style="font-size: 13px;color: rgb(136, 136, 136);">点击上方蓝色“</span><span style="color: rgb(24, 144, 255);font-size: 13px;" data-mce-style="font-size: 10px">后端面试那些事儿</span><span data-mce-style="font-size: 10px" style="font-size: 13px;color: rgb(136, 136, 136);">”,选择“设为星标”</span></p> <p data-lake-id="eca2a1864e13b3e1b84aafe9cb4abdff" style="text-align: center;font-size: 15px;color: rgb(64, 64, 64);line-height: 1.74;letter-spacing: 0.008em;outline-style: none;overflow-wrap: break-word;"><span style="color: rgb(140, 140, 140);font-size: 13px;" data-mce-style="font-size: 10px">学最好的别人,做最好的自己</span></p> <p data-lake-id="b4f10076adf2228ecaccd921f627ed69" style="text-align: right;font-size: 15px;color: rgb(64, 64, 64);line-height: 1.74;letter-spacing: 0.008em;outline-style: none;overflow-wrap: break-word;"><span style="color: rgb(140, 140, 140);font-size: 13px;" data-mce-style="font-size: 10px">来源:http://www.toutiao.com/i6677459303055491597</span></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">中大型项目中,一旦遇到数据量比较大,小伙伴应该都知道就应该对数据进行拆分了。<strong style="color: rgb(53, 179, 120);">有垂直和水平两种</strong>。</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><strong style="color: rgb(53, 179, 120);">垂直拆分</strong>比较简单,也就是本来一个数据库,数据量大之后,从业务角度进行拆分多个库。如下图,独立的拆分出订单库和用户库。</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/bdfc0ec5f6a59c4bba0523aafba09c62.jpg" data-type="jpeg" data-ratio="0.287962962962963" data-w="1080" data-backw="570" data-backh="164" style="width: 100%;height: auto;"></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><strong style="color: rgb(53, 179, 120);">水平拆分</strong>的概念,是同一个业务数据量大之后,进行水平拆分。</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/48656a9245aa7c9b6fc941b40452658c.jpg" data-type="jpeg" data-ratio="0.478125" data-w="640" data-backw="570" data-backh="273" style="width: 100%;height: auto;"></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">上图中订单数据达到了4000万,我们也知道mysql单表存储量推荐是百万级,如果不进行处理,mysql单表数据太大,会导致性能变慢。使用方案可以参考数据进行水平拆分。把4000万数据拆分4张表或者更多。当然也可以分库,再分表;把压力从数据库层级分开。</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><strong style="color: rgb(53, 179, 120);">分库分表方案</strong></p> <h3 style="margin-top: 1.2em;margin-bottom: 1em;color: rgb(53, 179, 120);font-weight: bold;font-size: 20px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">分库分表方案中有常用的方案,hash取模和range范围方案;分库分表方案最主要就是路由算法,把路由的key按照指定的算法进行路由存放。下边来介绍一下两个方案的特点。</h3> <h3 style="margin-top: 1.2em;margin-bottom: 1em;color: rgb(53, 179, 120);font-weight: bold;font-size: 20px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">1、hash取模方案</h3> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/b48e25e4d7953ef68d6ec7d1f7aa032.jpg" data-type="jpeg" data-ratio="0.459375" data-w="640" data-backw="570" data-backh="261" style="width: 100%;height: auto;"></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">在我们设计系统之前,可以先预估一下大概这几年的订单量,如:4000万。每张表我们可以容纳1000万,也我们可以设计4张表进行存储。</p> <blockquote style="margin: 10px 5px;border-top: none;border-right: 0px solid rgb(53, 179, 120);border-bottom: none;border-left-color: rgb(53, 179, 120);font-size: 0.9em;overflow: auto;background: rgb(251, 249, 253);color: rgb(97, 97, 97);padding: 10px 10px 10px 20px;quotes: none;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;"> <p style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;">那具体如何路由存储的呢?hash的方案就是对指定的路由key(如:id)对分表总数进行取模,上图中,id=12的订单,对4进行取模,也就是会得到0,那此订单会放到0表中。id=13的订单,取模得到为1,就会放到1表中。为什么对4取模,是因为分表总数是4。</p> </blockquote> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 15px;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);" class="list-paddingleft-2"> <li> <section style="margin-top: 10px;margin-bottom: 10px;line-height: 26px;color: rgb(1, 1, 1);"> 优点: </section></li> </ul> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">订单数据可以均匀的放到那4张表中,这样此订单进行操作时,就不会有热点问题。</p> <blockquote style="margin: 10px 5px;border-top: none;border-right: 0px solid rgb(53, 179, 120);border-bottom: none;border-left-color: rgb(53, 179, 120);font-size: 0.9em;overflow: auto;background: rgb(251, 249, 253);color: rgb(97, 97, 97);padding: 10px 10px 10px 20px;quotes: none;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;"> <p style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;">热点的含义:热点的意思就是对订单进行操作集中到1个表中,其他表的操作很少。</p> <p style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;">订单有个特点就是时间属性,一般用户操作订单数据,都会集中到这段时间产生的订单。如果这段时间产生的订单 都在同一张订单表中,那就会形成热点,那张表的压力会比较大。</p> </blockquote> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 15px;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);" class="list-paddingleft-2"> <li> <section style="margin-top: 10px;margin-bottom: 10px;line-height: 26px;color: rgb(1, 1, 1);"> 缺点: </section></li> </ul> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">将来的数据迁移和扩容,会很难。</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">如:业务发展很好,订单量很大,超出了4000万的量,那我们就需要增加分表数。如果我们增加4个表</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/f4a7df3038f737a09960e12c4e7b4dda.jpg" data-type="jpeg" data-ratio="0.4234375" data-w="640" data-backw="570" data-backh="241" style="width: 100%;height: auto;"></p> <blockquote style="margin: 10px 5px;border-top: none;border-right: 0px solid rgb(53, 179, 120);border-bottom: none;border-left-color: rgb(53, 179, 120);font-size: 0.9em;overflow: auto;background: rgb(251, 249, 253);color: rgb(97, 97, 97);padding: 10px 10px 10px 20px;quotes: none;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;"> <p style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;">一旦我们增加了分表的总数,取模的基数就会变成8,以前id=12的订单按照此方案就会到4表中查询,但之前的此订单时在0表的,这样就导致了数据查不到。就是因为取模的基数产生了变化。</p> </blockquote> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">遇到这个情况,我们小伙伴想到的方案就是做数据迁移,把之前的4000万数据,重新做一个hash方案,放到新的规划分表中。也就是我们要做数据迁移。这个是很痛苦的事情。有些小公司可以接受晚上停机迁移,但大公司是不允许停机做数据迁移的。</p> <blockquote style="margin: 10px 5px;border-top: none;border-right: 0px solid rgb(53, 179, 120);border-bottom: none;border-left-color: rgb(53, 179, 120);font-size: 0.9em;overflow: auto;background: rgb(251, 249, 253);color: rgb(97, 97, 97);padding: 10px 10px 10px 20px;quotes: none;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;"> <p style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;">当然做数据迁移可以结合自己的公司的业务,做一个工具进行,不过也带来了很多工作量,每次扩容都要做数据迁移</p> </blockquote> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">那有没有不需要做数据迁移的方案呢,我们看下面的方案</p> <h3 style="margin-top: 1.2em;margin-bottom: 1em;color: rgb(53, 179, 120);font-weight: bold;font-size: 20px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">2、range范围方案</h3> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">range方案也就是以范围进行拆分数据。</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/eda6f1d62e47b408e48d4557dd5d6bde.jpg" data-type="jpeg" data-ratio="0.403125" data-w="640" data-backw="570" data-backh="230" style="width: 100%;height: auto;"></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">range方案比较简单,就是把一定范围内的订单,存放到一个表中;如上图id=12放到0表中,id=1300万的放到1表中。设计这个方案时就是前期把表的范围设计好。通过id进行路由存放。</p> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 15px;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);" class="list-paddingleft-2"> <li> <section style="margin-top: 10px;margin-bottom: 10px;line-height: 26px;color: rgb(1, 1, 1);"> 优点 </section></li> </ul> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">我们小伙伴们想一下,此方案是不是有利于将来的扩容,不需要做数据迁移。即时再增加4张表,之前的4张表的范围不需要改变,id=12的还是在0表,id=1300万的还是在1表,新增的4张表他们的范围肯定是 大于 4000万之后的范围划分的。</p> <ul style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 15px;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);" class="list-paddingleft-2"> <li> <section style="margin-top: 10px;margin-bottom: 10px;line-height: 26px;color: rgb(1, 1, 1);"> 缺点 </section></li> </ul> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">有热点问题,我们想一下,因为id的值会一直递增变大,那这段时间的订单是不是会一直在某一张表中,如id=1000万 ~ id=2000万之间,这段时间产生的订单是不是都会集中到此张表中,这个就导致1表过热,压力过大,而其他的表没有什么压力。</p> <h3 style="margin-top: 1.2em;margin-bottom: 1em;color: rgb(53, 179, 120);font-weight: bold;font-size: 20px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">3、总结:</h3> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><strong style="color: rgb(53, 179, 120);">hash取模方案</strong>:没有热点问题,但扩容迁移数据痛苦</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><strong style="color: rgb(53, 179, 120);">range方案</strong>:不需要迁移数据,但有热点问题。</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">那有什么方案可以做到两者的优点结合呢?,<strong style="color: rgb(53, 179, 120);">即不需要迁移数据,又能解决数据热点的问题呢?</strong></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><strong style="color: rgb(53, 179, 120);">其实还有一个现实需求,能否根据服务器的性能以及存储高低,适当均匀调整存储呢?</strong></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/22e4e3c2663ac81b26646871b3e4446b.jpg" data-type="jpeg" data-ratio="0.3921875" data-w="640" data-backw="570" data-backh="224" style="width: 100%;height: auto;"></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><strong style="color: rgb(53, 179, 120);">方案思路</strong></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">hash是可以解决数据均匀的问题,range可以解决数据迁移问题,那我们可以不可以两者相结合呢?<strong style="color: rgb(53, 179, 120);">利用这两者的特性呢?</strong></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">我们考虑一下数据的扩容代表着,路由key(如id)的值变大了,这个是一定的,那我们先保证数据变大的时候,<strong style="color: rgb(53, 179, 120);">首先用range方案让数据落地到一个范围里面</strong>。这样以后id再变大,<strong style="color: rgb(53, 179, 120);">那以前的数据是不需要迁移的</strong>。</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">但又要考虑到<strong style="color: rgb(53, 179, 120);">数据均匀</strong>,那是不是可以在<strong style="color: rgb(53, 179, 120);">一定的范围内数据均匀</strong>的呢?因为我们每次的扩容肯定会<strong style="color: rgb(53, 179, 120);">事先设计好这次扩容的范围大小</strong>,我们只要<strong style="color: rgb(53, 179, 120);">保证这次的范围内的数据均匀</strong>是不是就ok了。</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/44c2b21b36da6c08733d32528d0ef8f1.jpg" data-type="jpeg" data-ratio="0.3953125" data-w="640" data-backw="570" data-backh="225" style="width: 100%;height: auto;"></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><strong style="color: rgb(53, 179, 120);">方案设计</strong></p> <h3 style="margin-top: 1.2em;margin-bottom: 1em;color: rgb(53, 179, 120);font-weight: bold;font-size: 20px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">我们先定义一个group组概念,这组里面包含了一些分库以及分表,如下图</h3> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/fd64a31a2e2a6027e418687efc281544.jpg" data-type="jpeg" data-ratio="0.6859375" data-w="640" data-backw="570" data-backh="391" style="width: 100%;height: auto;"></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">上图有几个关键点:</p> <blockquote style="margin: 10px 5px;border-top: none;border-right: 0px solid rgb(53, 179, 120);border-bottom: none;border-left-color: rgb(53, 179, 120);font-size: 0.9em;overflow: auto;background: rgb(251, 249, 253);color: rgb(97, 97, 97);padding: 10px 10px 10px 20px;quotes: none;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;"> <p style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;">1)id=0~4000万肯定落到group01组中</p> <p style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;">2)group01组有3个DB,那一个id如何路由到哪个DB?</p> <p style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;">3)根据hash取模定位DB,那模数为多少?模数要为所有此group组DB中的表数,上图总表数为10。为什么要去表的总数?而不是DB总数3呢?</p> <p style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;">4)如id=12,id%10=2;那值为2,落到哪个DB库呢?这是设计是前期设定好的,那怎么设定的呢?</p> <p style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;">5)一旦设计定位哪个DB后,就需要确定落到DB中的哪张表呢?</p> </blockquote> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/fc377023bd257a2f1530627e58814ef6.jpg" data-type="jpeg" data-ratio="0.384375" data-w="640" data-backw="570" data-backh="219" style="width: 100%;height: auto;"></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><strong style="color: rgb(53, 179, 120);">核心主流程</strong></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/ca4e12b0acd2444315b39c9a4530ff58.jpg" data-type="jpeg" data-ratio="0.5703125" data-w="640" data-backw="570" data-backh="325" style="width: 100%;height: auto;"></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">按照上面的流程,我们就可以根据此规则,定位一个id,我们看看有没有避免热点问题。</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">我们看一下,id在【0,1000万】范围内的,根据上面的流程设计,1000万以内的id都均匀的分配到DB_0,DB_1,DB_2三个数据库中的Table_0表中,为什么可以均匀,因为我们用了hash的方案,对10进行取模。</p> <blockquote style="margin: 10px 5px;border-top: none;border-right: 0px solid rgb(53, 179, 120);border-bottom: none;border-left-color: rgb(53, 179, 120);font-size: 0.9em;overflow: auto;background: rgb(251, 249, 253);color: rgb(97, 97, 97);padding: 10px 10px 10px 20px;quotes: none;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;"> <p style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;">上面我们也提了疑问,为什么对表的总数10取模,而不是DB的总数3进行取模?我们看一下为什么DB_0是4张表,其他两个DB_1是3张表?</p> </blockquote> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">在我们安排服务器时,有些服务器的性能高,存储高,就可以安排多存放些数据,有些性能低的就少放点数据。如果我们取模是按照DB总数3,进行取模,那就代表着【0,4000万】的数据是平均分配到3个DB中的,那就不能够实现按照服务器能力适当分配了。</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">按照Table总数10就能够达到,看如何达到</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/2dff4480685806c3686bed06ffef151b.jpg" data-type="jpeg" data-ratio="0.6734375" data-w="640" data-backw="570" data-backh="384" style="width: 100%;height: auto;"></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">上图中我们对10进行取模,如果值为【0,1,2,3】就路由到DB_0,【4,5,6】路由到DB_1,【7,8,9】路由到DB_2。现在小伙伴们有没有理解,这样的设计就可以把多一点的数据放到DB_0中,其他2个DB数据量就可以少一点。DB_0承担了4/10的数据量,DB_1承担了3/10的数据量,DB_2也承担了3/10的数据量。整个Group01承担了【0,4000万】的数据量。</p> <blockquote style="margin: 10px 5px;border-top: none;border-right: 0px solid rgb(53, 179, 120);border-bottom: none;border-left-color: rgb(53, 179, 120);font-size: 0.9em;overflow: auto;background: rgb(251, 249, 253);color: rgb(97, 97, 97);padding: 10px 10px 10px 20px;quotes: none;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;"> <p style="font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;">注意:小伙伴千万不要被DB_1或DB_2中table的范围也是0~4000万疑惑了,这个是范围区间,也就是id在哪些范围内,落地到哪个表而已。</p> </blockquote> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">上面一大段的介绍,就解决了热点的问题,以及可以按照服务器指标,设计数据量的分配。</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/70a583d57b9ed399cf0b6271e2d032c2.jpg" data-type="jpeg" data-ratio="0.390625" data-w="640" data-backw="570" data-backh="222" style="width: 100%;height: auto;"></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><strong style="color: rgb(53, 179, 120);">如何扩容</strong></p> <h3 style="margin-top: 1.2em;margin-bottom: 1em;color: rgb(53, 179, 120);font-weight: bold;font-size: 20px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">其实上面设计思路理解了,扩容就已经出来了;那就是扩容的时候再设计一个group02组,定义好此group的数据范围就ok了。</h3> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/84a846af5434abe0694bdc2d2ec37cf8.jpg" data-type="jpeg" data-ratio="0.759375" data-w="640" data-backw="570" data-backh="433" style="width: 100%;height: auto;"></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">因为是新增的一个group01组,所以就没有什么数据迁移概念,完全是新增的group组,而且这个group组照样就防止了热点,也就是【4000万,5500万】的数据,都均匀分配到三个DB的table_0表中,【5500万~7000万】数据均匀分配到table_1表中。</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><strong style="color: rgb(53, 179, 120);">系统设计</strong></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/6352534b3bb678a31986d9022410ad19.jpg" data-type="jpeg" data-ratio="0.396875" data-w="640" data-backw="570" data-backh="226" style="width: 100%;height: auto;"></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">思路确定了,设计是比较简单的,就3张表,把group,DB,table之间建立好关联关系就行了。</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: center;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/a026661b1f50d160be5a339ceef099b9.jpg" data-type="jpeg" data-ratio="0.6578125" data-w="640" data-backw="570" data-backh="375" style="width: 100%;height: auto;">group和DB的关系</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: center;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/e420bfa5beffa91349cebaf7a551ab31.jpg" data-type="jpeg" data-ratio="0.6890625" data-w="640" data-backw="570" data-backh="393" style="width: 100%;height: auto;">table和db的关系</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">上面的表关联其实是比较简单的,只要原理思路理顺了,就ok了。小伙伴们在开发的时候不要每次都去查询三张关联表,可以保存到缓存中(本地jvm缓存),这样不会影响性能。</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);"><img src="/upload/8c69b24263929784e268002a86fe3bd8.jpg" data-type="jpeg" data-ratio="0.3984375" data-w="640" data-backw="570" data-backh="227" style="width: 100%;height: auto;"></p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">一旦需要扩容,小伙伴是不是要增加一下group02关联关系,那应用服务需要重新启动吗?</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">简单点的话,就凌晨配置,重启应用服务就行了。但如果是大型公司,是不允许的,因为凌晨也有订单的。那怎么办呢?本地jvm缓存怎么更新呢?</p> <p style="margin: 1em 4px;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);">其实方案也很多,可以使用用zookeeper,也可以使用分布式配置,这里是比较推荐使用分布式配置中心的,可以将这些数据配置到分布式配置中心去。</p> <p data-lake-id="b4f10076adf2228ecaccd921f627ed69" style="text-align: center;font-size: 15px;color: rgb(64, 64, 64);line-height: 1.74;letter-spacing: 0.008em;outline-style: none;overflow-wrap: break-word;"><br></p> <section data-mpa-template="t" mpa-from-tpl="t"> <section mpa-from-tpl="t" style="margin-top: 10px;margin-bottom: 10px;"> <p style="margin-right: auto;margin-left: auto;width: 231.1875px;"><img data-ratio="0.16666666666666666" src="/upload/89aa6c9fe16e0dfcf56dad1a9f9078ff.png" data-type="gif" data-w="300" style="width: auto;"></p> </section> </section> <p data-lake-id="098b923ca3e65e99528d2c30d6cf4c26" style="text-align: center;font-size: 15px;color: rgb(64, 64, 64);line-height: 1.74;letter-spacing: 0.008em;outline-style: none;overflow-wrap: break-word;"><br></p> <section data-recommend-type="list-title" data-recommend-tid="6" data-mpa-template="t" style="width: 100%;display: flex;justify-content: center;align-items: center;" data-mid="" data-from="yb-recommend"> <section style="width: 100%;padding: 14px;background: rgb(255, 255, 255);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(232, 232, 235);" data-mid=""> <section style="width: 100%;display: flex;justify-content: center;align-items: center;align-items: flex-end;" data-mid=""> <section data-mid="" style="height: 28px;padding: 4px 22px;font-size: 14px;font-weight: 500;color: rgb(19, 52, 86);line-height: 20px;background-image: url("https://mmbiz.qpic.cn/mmbiz_png/sUbvrqLicbpzB81mjeBxPuxnYdalGxNnJo30L2Hq3WwGficcq8w5YJkLeXnsNHocN53k55TfN5mBpCdicGRyfDg1g/640?wx_fmt=png");background-repeat: no-repeat;background-size: 100% 100%;margin-bottom: -14px;z-index: 10;"> <p data-mid="">往期推荐</p> </section> </section> <section style="width: 100%;border-width: 1px;border-style: solid;border-color: rgb(198, 226, 255);padding: 17px 16px 9px;" data-mid=""> <section data-mpa-template="t" data-recommend-article-type="list-title" data-recomment-template-id="6" data-recommend-article-id="2247494136_1" data-recommend-article-time="1619586060" data-recommend-article-cover="http://mmbiz.qpic.cn/mmbiz_jpg/HmHDU48icAtYAibA5pia38qvibkpjPgcg2cQkuibibppCIJoNGicrlft4mUNzZMJbffWVXM46FWKCCf9OMR5skuNE11zQ/0?wx_fmt=jpeg" data-recommend-article-title="那些在一个公司死磕了5-10年的人,最后都怎么样了?那些在一个公司死磕了5-10年的人,最后都怎么样了?" data-recommend-article-content-url="http://mp.weixin.qq.com/s?__biz=MzIxMzQzNzMwMw==&mid=2247494136&idx=1&sn=3904261097874790edf276c601574240&chksm=97b477e0a0c3fef6ce269812388cd645dd7824bb53f5df229b789073fd23555a3d4da68fbbd6#rd"> <a href="http://mp.weixin.qq.com/s?__biz=MzIxMzQzNzMwMw==&mid=2247494136&idx=1&sn=3904261097874790edf276c601574240&chksm=97b477e0a0c3fef6ce269812388cd645dd7824bb53f5df229b789073fd23555a3d4da68fbbd6&scene=21#wechat_redirect" data-linktype="2"> <section data-recommend-title="t" data-recommend-content="t" style="width: 100%;display: flex;justify-content: center;align-items: center;flex-wrap: nowrap;border-bottom: 1px dashed #c6e2ff;padding: 6px;font-size: 13px;font-weight: 400;color: #2c5f95;line-height: 18px;" data-mid=""> <p style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width: 100%;" data-mid="">那些在一个公司死磕了5-10年的人,最后都怎么样了?那些在一个公司死磕了5-10年的人,最后都怎么样了?</p> </section></a> </section> <section data-mpa-template="t" data-recommend-article-type="list-title" data-recomment-template-id="6" data-recommend-article-id="2247494136_2" data-recommend-article-time="1619586060" data-recommend-article-cover="http://mmbiz.qpic.cn/mmbiz_jpg/R3InYSAIZkEia7KiaqqO9Qlic7tnKTIiaUHo80kapwM2vQ63xhM1V0U8nQtUhDqNS4RlVdEbygK9duWOcJeg1CkLPQ/0?wx_fmt=jpeg" data-recommend-article-title="年终凡尔赛,都是别人家的公司..." data-recommend-article-content-url="http://mp.weixin.qq.com/s?__biz=MzIxMzQzNzMwMw==&mid=2247494136&idx=2&sn=9db2c0ad2c61f47e7d8aaa94b1ad9ba4&chksm=97b477e0a0c3fef66d7cdda34eb702c1b599125988870d326f375d9c7e5f3ecf77f516006213#rd"> <a href="http://mp.weixin.qq.com/s?__biz=MzIxMzQzNzMwMw==&mid=2247494136&idx=2&sn=9db2c0ad2c61f47e7d8aaa94b1ad9ba4&chksm=97b477e0a0c3fef66d7cdda34eb702c1b599125988870d326f375d9c7e5f3ecf77f516006213&scene=21#wechat_redirect" data-linktype="2"> <section data-recommend-title="t" data-recommend-content="t" style="width: 100%;display: flex;justify-content: center;align-items: center;flex-wrap: nowrap;border-bottom: 1px dashed #c6e2ff;padding: 6px;font-size: 13px;font-weight: 400;color: #2c5f95;line-height: 18px;" data-mid=""> <p style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width: 100%;" data-mid="">年终凡尔赛,都是别人家的公司...</p> </section></a> </section> <section data-mpa-template="t" data-recommend-article-type="list-title" data-recomment-template-id="6" data-recommend-article-id="2247494125_1" data-recommend-article-time="1619499660" data-recommend-article-cover="http://mmbiz.qpic.cn/mmbiz_jpg/HmHDU48icAtbE3whoH0CjpsMRvtkbQiaQbPX3AKIAnOTVGrgeVibDVzFI1sZsI1RoZjslRrO5GF33Cb9YVnz4x1bg/0?wx_fmt=jpeg" data-recommend-article-title="面试官:Redis新版本开始引入多线程,谈谈你的看法?" data-recommend-article-content-url="http://mp.weixin.qq.com/s?__biz=MzIxMzQzNzMwMw==&mid=2247494125&idx=1&sn=0d61e4b3526795009aea9e282b63fed0&chksm=97b477f5a0c3fee30135015a6581a7d926e27a3bf6ee55810988f9aebae1fd868d37fe19fc5d#rd"> <a href="http://mp.weixin.qq.com/s?__biz=MzIxMzQzNzMwMw==&mid=2247494125&idx=1&sn=0d61e4b3526795009aea9e282b63fed0&chksm=97b477f5a0c3fee30135015a6581a7d926e27a3bf6ee55810988f9aebae1fd868d37fe19fc5d&scene=21#wechat_redirect" data-linktype="2"> <section data-recommend-title="t" data-recommend-content="t" style="width: 100%;display: flex;justify-content: center;align-items: center;flex-wrap: nowrap;border-bottom: 1px dashed #c6e2ff;padding: 6px;font-size: 13px;font-weight: 400;color: #2c5f95;line-height: 18px;" data-mid=""> <p style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width: 100%;" data-mid="">面试官:Redis新版本开始引入多线程,谈谈你的看法?</p> </section></a> </section> <section data-mpa-template="t" data-recommend-article-type="list-title" data-recomment-template-id="6" data-recommend-article-id="2247494125_2" data-recommend-article-time="1619499660" data-recommend-article-cover="http://mmbiz.qpic.cn/mmbiz_jpg/R3InYSAIZkEuia6flEa2fa6eK2hn8ZxK9NXd0raGFT1ZAOGtRLISJQIctgGciaf3banwYJNXic8dxcmwyzbSacicdw/0?wx_fmt=jpeg" data-recommend-article-title="百度申请“员工工作状态预测”专利,意欲何为?" data-recommend-article-content-url="http://mp.weixin.qq.com/s?__biz=MzIxMzQzNzMwMw==&mid=2247494125&idx=2&sn=2992b507af2ee84886ee6d9af52041b0&chksm=97b477f5a0c3fee335374c450b3abc26aae93039e9cc42e9acfd61ace153eebab8bdbab747f4#rd"> <a href="http://mp.weixin.qq.com/s?__biz=MzIxMzQzNzMwMw==&mid=2247494125&idx=2&sn=2992b507af2ee84886ee6d9af52041b0&chksm=97b477f5a0c3fee335374c450b3abc26aae93039e9cc42e9acfd61ace153eebab8bdbab747f4&scene=21#wechat_redirect" data-linktype="2"> <section data-recommend-title="t" data-recommend-content="t" style="width: 100%;display: flex;justify-content: center;align-items: center;flex-wrap: nowrap;border-bottom: 1px dashed #c6e2ff;padding: 6px;font-size: 13px;font-weight: 400;color: #2c5f95;line-height: 18px;" data-mid=""> <p style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width: 100%;" data-mid="">百度申请“员工工作状态预测”专利,意欲何为?</p> </section></a> </section> <section data-mpa-template="t" data-recommend-article-type="list-title" data-recomment-template-id="6" data-recommend-article-id="2247494111_1" data-recommend-article-time="1619413260" data-recommend-article-cover="http://mmbiz.qpic.cn/mmbiz_jpg/HmHDU48icAtb2VU4TEibmN0o5BibyxSicv5REGdVqnI8ibzobGVXBpu8coFdwG2ibA1vodnGYDmnB1p0ecnFpmBqiaWpQ/0?wx_fmt=jpeg" data-recommend-article-title="诡异!MyBatis的Insert方法一直返回"-2147482646"?" data-recommend-article-content-url="http://mp.weixin.qq.com/s?__biz=MzIxMzQzNzMwMw==&mid=2247494111&idx=1&sn=976ec0ccc19b1a0afcb0a5e29426e158&chksm=97b477c7a0c3fed194a46f4b1d96cdfe54a1959c3c9b0ca810cdfa6c8b1b218e6b4c4c50493c#rd"> <a href="http://mp.weixin.qq.com/s?__biz=MzIxMzQzNzMwMw==&mid=2247494111&idx=1&sn=976ec0ccc19b1a0afcb0a5e29426e158&chksm=97b477c7a0c3fed194a46f4b1d96cdfe54a1959c3c9b0ca810cdfa6c8b1b218e6b4c4c50493c&scene=21#wechat_redirect" data-linktype="2"> <section data-recommend-title="t" data-recommend-content="t" style="width: 100%;display: flex;justify-content: center;align-items: center;flex-wrap: nowrap;border-bottom: 1px dashed #c6e2ff;padding: 6px;font-size: 13px;font-weight: 400;color: #2c5f95;line-height: 18px;" data-mid=""> <p style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width: 100%;" data-mid="">诡异!MyBatis的Insert方法一直返回"-2147482646"?</p> </section></a> </section> <section data-mpa-template="t" data-recommend-article-type="list-title" data-recomment-template-id="6" data-recommend-article-id="2247494111_2" data-recommend-article-time="1619413260" data-recommend-article-cover="http://mmbiz.qpic.cn/mmbiz_jpg/R3InYSAIZkFhFBeGr1LqJcEgDZQv9Jj6VgoMYNOjLpcH51gJibicJ15Tu6GEaF4smB79QMcLDbG0u0z0iaSKAcsBA/0?wx_fmt=jpeg" data-recommend-article-title="Spring在Java领域的统治地位:86% 的Java开发者依赖它!" data-recommend-article-content-url="http://mp.weixin.qq.com/s?__biz=MzIxMzQzNzMwMw==&mid=2247494111&idx=2&sn=d3f3f37471367d384cb4290a4fac1bd4&chksm=97b477c7a0c3fed1bfa68b2a8b04a995b0e16102fb48825a3550fe5fedb0dc8e6bd681661fbe#rd"> <a href="http://mp.weixin.qq.com/s?__biz=MzIxMzQzNzMwMw==&mid=2247494111&idx=2&sn=d3f3f37471367d384cb4290a4fac1bd4&chksm=97b477c7a0c3fed1bfa68b2a8b04a995b0e16102fb48825a3550fe5fedb0dc8e6bd681661fbe&scene=21#wechat_redirect" data-linktype="2"> <section data-recommend-title="t" data-recommend-content="t" style="width: 100%;display: flex;justify-content: center;align-items: center;flex-wrap: nowrap;border-bottom: 1px dashed #c6e2ff;padding: 6px;font-size: 13px;font-weight: 400;color: #2c5f95;line-height: 18px;border-bottom:none !important;" data-mid=""> <p style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width: 100%;" data-mid="">Spring在Java领域的统治地位:86% 的Java开发者依赖它!</p> </section></a> </section> </section> </section> </section> <p data-lake-id="098b923ca3e65e99528d2c30d6cf4c26" style="text-align: center;font-size: 15px;color: rgb(64, 64, 64);line-height: 1.74;letter-spacing: 0.008em;outline-style: none;overflow-wrap: break-word;"><br></p> <section data-mpa-template="t" mpa-from-tpl="t" style="white-space: normal;"> <p style="text-align: center;"><strong><span style="color: rgb(140, 140, 140);letter-spacing: 0.008em;font-size: 14px;">一起进大厂,每日学干货</span></strong></p> </section> <section style="margin-top: 5px;white-space: normal;text-align: center;font-size: 15px;color: rgb(64, 64, 64);line-height: 1.74;letter-spacing: 0.008em;outline-style: none;overflow-wrap: break-word;"> <span style="color: rgb(0, 0, 0);"><strong><span style="font-size: 14px;">关注我回复【</span></strong></span> <span style="color: rgb(255, 76, 65);"><strong><span style="font-size: 14px;">加群</span></strong></span> <span style="color: rgb(0, 0, 0);"><strong><span style="color: rgb(0, 0, 0);font-size: 14px;">】,加入Java技术交流群</span></strong></span> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <p style="text-align: center;"><img data-ratio="0.5982532751091703" src="/upload/4e21037b66f60f7d73d060863de4b4b5.png" data-type="gif" data-w="458" data-width="100%" style="color: rgb(62, 62, 62);font-size: 16px;vertical-align: middle;width: 62.0938px;"></p> <section class="mp_profile_iframe_wrp"> <mpprofile class="js_uneditable custom_select_card mp_profile_iframe" data-pluginname="mpprofile" data-id="MzIxMzQzNzMwMw==" data-headimg="http://mmbiz.qpic.cn/mmbiz_png/HmHDU48icAtYvlypOY9VaGVXQ639L63Iq6zHiclgibG0CAhgrJ2JLRibKbeCgVIx7WXcicbMW6AJL1Hos9AoJTqtVfA/0?wx_fmt=png" data-nickname="后端面试那些事" data-alias="" data-signature="专注分享后端干货!面向大厂,一起进步!" data-from="0"></mpprofile> </section> </section> <p style="text-align: center;"><br></p> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-role="paragraph" mpa-from-tpl="t" style="white-space: normal;border-width: 0px;border-style: none;border-color: initial;"> <section style="box-sizing: border-box;font-size: 16px;"> <section powered-by="xiumi.us" style="margin-top: 0.5em;box-sizing: border-box;"> <section style="padding: 0.5em;border-width: 1px;border-style: solid;border-color: rgb(249, 110, 87);box-shadow: rgb(226, 226, 226) 0px 16px 1px -13px;box-sizing: border-box;"> <section powered-by="xiumi.us" style="text-align: left;box-sizing: border-box;"> <section style="text-align: justify;color: rgb(64, 84, 115);box-sizing: border-box;"> <p style="box-sizing: border-box;"><img src="/upload/a53e4e397528931045198e4f89d7ba0.png" data-type="png" data-ratio="0.33611111111111114" data-w="1080"></p> <p style="box-sizing: border-box;">点击“阅读原文”,领取 2021 年<strong>最新免费技术资料大全</strong></p> </section> </section> </section> </section> <section powered-by="xiumi.us" style="font-size: 32px;color: rgb(249, 110, 87);box-sizing: border-box;text-align: left;"> ↓↓↓ </section> </section> </section> </section>
作者:微信小助手
<p style="white-space: normal;text-align: center;" data-mpa-powered-by="yiban.io"><span style="color: rgb(178, 178, 178);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 14px;letter-spacing: 0.75px;text-align: center;word-spacing: 0.8px;background-color: rgb(255, 255, 255);">回复 PDF 领取资料</span> </p> <p style="white-space: normal;text-align: center;"><img data-ratio="0.42533333333333334" src="/upload/ba707c194fa3fb5e2db663344bd2a057.png" data-type="png" data-w="2250"></p> <p data-darkmode-color-15906764299112="rgb(230, 230, 230)" data-darkmode-original-color-15906764299112="rgb(0, 0, 0)" data-darkmode-bgcolor-15906764299112="rgb(36, 36, 36)" data-darkmode-original-bgcolor-15906764299112="rgb(255, 255, 255)" data-style="margin-top: 10px; margin-bottom: 10px; background-color: rgb(255, 255, 255); color: rgb(0, 0, 0); font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif; font-size: 16px; white-space: normal; word-spacing: 0.8px; letter-spacing: 0.75px; text-align: center; visibility: visible;" class="js_darkmode__1" data-darkmode-color-15958675267961="rgb(163, 163, 163)" data-darkmode-original-color-15958675267961="rgb(0, 0, 0)" data-darkmode-bgcolor-15958675267961="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15958675267961="rgb(255, 255, 255)" data-darkmode-color-15965526125846="rgb(163, 163, 163)" data-darkmode-original-color-15965526125846="rgb(0, 0, 0)" data-darkmode-bgcolor-15965526125846="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15965526125846="rgb(255, 255, 255)" data-darkmode-bgcolor-15969880239317="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15969880239317="rgb(255, 255, 255)" data-darkmode-color-15969880239317="rgb(163, 163, 163)" data-darkmode-original-color-15969880239317="rgb(0, 0, 0)" data-darkmode-color-15976750929548="rgb(163, 163, 163)" data-darkmode-original-color-15976750929548="rgb(0, 0, 0)" data-darkmode-bgcolor-15976750929548="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15976750929548="rgb(255, 255, 255)" data-darkmode-color-15982803404507="rgb(163, 163, 163)" data-darkmode-original-color-15982803404507="rgb(0, 0, 0)" data-darkmode-bgcolor-15982803404507="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15982803404507="rgb(255, 255, 255)" style="margin-top: 10px;margin-bottom: 10px;white-space: normal;max-width: 100%;min-height: 1em;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;background-color: rgb(255, 255, 255);font-size: 16px;word-spacing: 0.8px;text-align: center;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span data-darkmode-color-15906764299112="rgb(230, 230, 230)" data-darkmode-original-color-15906764299112="rgb(0, 0, 0)" data-darkmode-bgcolor-15906764299112="rgb(36, 36, 36)" data-darkmode-original-bgcolor-15906764299112="rgb(255, 255, 255)" data-darkmode-color-15958675267961="rgb(163, 163, 163)" data-darkmode-original-color-15958675267961="rgb(0, 0, 0)" data-darkmode-bgcolor-15958675267961="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15958675267961="rgb(255, 255, 255)" data-darkmode-color-15965526125846="rgb(163, 163, 163)" data-darkmode-original-color-15965526125846="rgb(0, 0, 0)" data-darkmode-bgcolor-15965526125846="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15965526125846="rgb(255, 255, 255)" data-darkmode-bgcolor-15969880239317="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15969880239317="rgb(255, 255, 255)" data-darkmode-color-15969880239317="rgb(163, 163, 163)" data-darkmode-original-color-15969880239317="rgb(0, 0, 0)" data-darkmode-color-15976750929548="rgb(163, 163, 163)" data-darkmode-original-color-15976750929548="rgb(0, 0, 0)" data-darkmode-bgcolor-15976750929548="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15976750929548="rgb(255, 255, 255)" data-darkmode-color-15982803404507="rgb(163, 163, 163)" data-darkmode-original-color-15982803404507="rgb(0, 0, 0)" data-darkmode-bgcolor-15982803404507="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15982803404507="rgb(255, 255, 255)" style="max-width: 100%;font-size: 14px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="color: rgb(0, 0, 0);">这是悟空的第 </span><span style="color: rgb(255, 104, 39);">99</span></span><span data-darkmode-color-15906764299112="rgb(230, 230, 230)" data-darkmode-original-color-15906764299112="rgb(0, 0, 0)" data-darkmode-bgcolor-15906764299112="rgb(36, 36, 36)" data-darkmode-original-bgcolor-15906764299112="rgb(255, 255, 255)" data-darkmode-color-15958675267961="rgb(163, 163, 163)" data-darkmode-original-color-15958675267961="rgb(0, 0, 0)" data-darkmode-bgcolor-15958675267961="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15958675267961="rgb(255, 255, 255)" data-darkmode-color-15965526125846="rgb(163, 163, 163)" data-darkmode-original-color-15965526125846="rgb(0, 0, 0)" data-darkmode-bgcolor-15965526125846="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15965526125846="rgb(255, 255, 255)" data-darkmode-bgcolor-15969880239317="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15969880239317="rgb(255, 255, 255)" data-darkmode-color-15969880239317="rgb(163, 163, 163)" data-darkmode-original-color-15969880239317="rgb(0, 0, 0)" data-darkmode-color-15976750929548="rgb(163, 163, 163)" data-darkmode-original-color-15976750929548="rgb(0, 0, 0)" data-darkmode-bgcolor-15976750929548="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15976750929548="rgb(255, 255, 255)" data-darkmode-color-15982803404507="rgb(163, 163, 163)" data-darkmode-original-color-15982803404507="rgb(0, 0, 0)" data-darkmode-bgcolor-15982803404507="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15982803404507="rgb(255, 255, 255)" style="color: rgb(0, 0, 0);max-width: 100%;font-size: 14px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"> 篇原创文章</span><br data-darkmode-color-15982803404507="rgb(163, 163, 163)" data-darkmode-original-color-15982803404507="rgb(0, 0, 0)" data-darkmode-bgcolor-15982803404507="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15982803404507="rgb(255, 255, 255)" style="max-width: 100%;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p> <p data-tool="mdnice编辑器" data-darkmode-color-15906764299112="rgb(230, 230, 230)" data-darkmode-original-color-15906764299112="rgb(0, 0, 0)" data-darkmode-bgcolor-15906764299112="rgb(36, 36, 36)" data-darkmode-original-bgcolor-15906764299112="rgb(255, 255, 255)" data-style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0); font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif; font-size: 16px; white-space: normal; word-spacing: 0.8px; letter-spacing: 0.75px; text-align: center; visibility: visible;" class="js_darkmode__2" data-darkmode-color-15958675267961="rgb(163, 163, 163)" data-darkmode-original-color-15958675267961="rgb(0, 0, 0)" data-darkmode-bgcolor-15958675267961="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15958675267961="rgb(255, 255, 255)" data-darkmode-color-15965526125846="rgb(163, 163, 163)" data-darkmode-original-color-15965526125846="rgb(0, 0, 0)" data-darkmode-bgcolor-15965526125846="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15965526125846="rgb(255, 255, 255)" data-darkmode-bgcolor-15969880239317="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15969880239317="rgb(255, 255, 255)" data-darkmode-color-15969880239317="rgb(163, 163, 163)" data-darkmode-original-color-15969880239317="rgb(0, 0, 0)" data-darkmode-color-15976750929548="rgb(163, 163, 163)" data-darkmode-original-color-15976750929548="rgb(0, 0, 0)" data-darkmode-bgcolor-15976750929548="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15976750929548="rgb(255, 255, 255)" data-darkmode-color-15982803404507="rgb(163, 163, 163)" data-darkmode-original-color-15982803404507="rgb(0, 0, 0)" data-darkmode-bgcolor-15982803404507="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15982803404507="rgb(255, 255, 255)" style="white-space: normal;max-width: 100%;min-height: 1em;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;background-color: rgb(255, 255, 255);color: rgb(0, 0, 0);font-size: 16px;word-spacing: 0.8px;text-align: center;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span data-darkmode-color-15906764299112="rgb(178, 178, 178)" data-darkmode-original-color-15906764299112="rgb(178, 178, 178)" data-darkmode-bgcolor-15906764299112="rgb(36, 36, 36)" data-darkmode-original-bgcolor-15906764299112="rgb(255, 255, 255)" data-darkmode-color-15958675267961="rgb(163, 163, 163)" data-darkmode-original-color-15958675267961="rgb(178, 178, 178)" data-darkmode-bgcolor-15958675267961="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15958675267961="rgb(255, 255, 255)" data-style="color: rgb(178, 178, 178); font-size: 14px; visibility: visible;" class="js_darkmode__3" data-darkmode-color-15965526125846="rgb(163, 163, 163)" data-darkmode-original-color-15965526125846="rgb(178, 178, 178)" data-darkmode-bgcolor-15965526125846="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15965526125846="rgb(255, 255, 255)" data-darkmode-bgcolor-15969880239317="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15969880239317="rgb(255, 255, 255)" data-darkmode-color-15969880239317="rgb(163, 163, 163)" data-darkmode-original-color-15969880239317="rgb(178, 178, 178)" data-darkmode-color-15976750929548="rgb(163, 163, 163)" data-darkmode-original-color-15976750929548="rgb(178, 178, 178)" data-darkmode-bgcolor-15976750929548="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15976750929548="rgb(255, 255, 255)" data-darkmode-color-15982803404507="rgb(163, 163, 163)" data-darkmode-original-color-15982803404507="rgb(178, 178, 178)" data-darkmode-bgcolor-15982803404507="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15982803404507="rgb(255, 255, 255)" style="max-width: 100%;color: rgb(178, 178, 178);font-size: 14px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">作者 | 悟空聊架构</span></p> <p data-tool="mdnice编辑器" data-darkmode-color-15906764299112="rgb(230, 230, 230)" data-darkmode-original-color-15906764299112="rgb(0, 0, 0)" data-darkmode-bgcolor-15906764299112="rgb(36, 36, 36)" data-darkmode-original-bgcolor-15906764299112="rgb(255, 255, 255)" data-style="background-color: rgb(255, 255, 255); color: rgb(0, 0, 0); font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif; font-size: 16px; white-space: normal; word-spacing: 0.8px; letter-spacing: 0.75px; text-align: center; visibility: visible;" class="js_darkmode__4" data-darkmode-color-15958675267961="rgb(163, 163, 163)" data-darkmode-original-color-15958675267961="rgb(0, 0, 0)" data-darkmode-bgcolor-15958675267961="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15958675267961="rgb(255, 255, 255)" data-darkmode-color-15965526125846="rgb(163, 163, 163)" data-darkmode-original-color-15965526125846="rgb(0, 0, 0)" data-darkmode-bgcolor-15965526125846="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15965526125846="rgb(255, 255, 255)" data-darkmode-bgcolor-15969880239317="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15969880239317="rgb(255, 255, 255)" data-darkmode-color-15969880239317="rgb(163, 163, 163)" data-darkmode-original-color-15969880239317="rgb(0, 0, 0)" data-darkmode-color-15976750929548="rgb(163, 163, 163)" data-darkmode-original-color-15976750929548="rgb(0, 0, 0)" data-darkmode-bgcolor-15976750929548="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15976750929548="rgb(255, 255, 255)" data-darkmode-color-15982803404507="rgb(163, 163, 163)" data-darkmode-original-color-15982803404507="rgb(0, 0, 0)" data-darkmode-bgcolor-15982803404507="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15982803404507="rgb(255, 255, 255)" style="white-space: normal;max-width: 100%;min-height: 1em;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;background-color: rgb(255, 255, 255);color: rgb(0, 0, 0);font-size: 16px;word-spacing: 0.8px;text-align: center;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span data-darkmode-color-15906764299112="rgb(178, 178, 178)" data-darkmode-original-color-15906764299112="rgb(178, 178, 178)" data-darkmode-bgcolor-15906764299112="rgb(36, 36, 36)" data-darkmode-original-bgcolor-15906764299112="rgb(255, 255, 255)" data-darkmode-color-15958675267961="rgb(163, 163, 163)" data-darkmode-original-color-15958675267961="rgb(178, 178, 178)" data-darkmode-bgcolor-15958675267961="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15958675267961="rgb(255, 255, 255)" data-style="color: rgb(178, 178, 178); font-size: 14px; visibility: visible;" class="js_darkmode__5" data-darkmode-color-15965526125846="rgb(163, 163, 163)" data-darkmode-original-color-15965526125846="rgb(178, 178, 178)" data-darkmode-bgcolor-15965526125846="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15965526125846="rgb(255, 255, 255)" data-darkmode-bgcolor-15969880239317="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15969880239317="rgb(255, 255, 255)" data-darkmode-color-15969880239317="rgb(163, 163, 163)" data-darkmode-original-color-15969880239317="rgb(178, 178, 178)" data-darkmode-color-15976750929548="rgb(163, 163, 163)" data-darkmode-original-color-15976750929548="rgb(178, 178, 178)" data-darkmode-bgcolor-15976750929548="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15976750929548="rgb(255, 255, 255)" data-darkmode-color-15982803404507="rgb(163, 163, 163)" data-darkmode-original-color-15982803404507="rgb(178, 178, 178)" data-darkmode-bgcolor-15982803404507="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15982803404507="rgb(255, 255, 255)" style="max-width: 100%;color: rgb(178, 178, 178);font-size: 14px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">来源 | <span style="letter-spacing: 0.75px;word-spacing: 0.8px;">悟空聊架构</span>(ID:PassJava666)</span></p> <section data-darkmode-color-15906764299112="rgb(230, 230, 230)" data-darkmode-original-color-15906764299112="rgb(0, 0, 0)" data-darkmode-bgcolor-15906764299112="rgb(36, 36, 36)" data-darkmode-original-bgcolor-15906764299112="rgb(255, 255, 255)" data-style="margin-bottom: 20px; background-color: rgb(255, 255, 255); color: rgb(0, 0, 0); font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif; font-size: 16px; white-space: normal; word-spacing: 0.8px; letter-spacing: 0.75px; text-align: center; visibility: visible;" class="js_darkmode__6" data-darkmode-color-15958675267961="rgb(163, 163, 163)" data-darkmode-original-color-15958675267961="rgb(0, 0, 0)" data-darkmode-bgcolor-15958675267961="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15958675267961="rgb(255, 255, 255)" data-darkmode-color-15965526125846="rgb(163, 163, 163)" data-darkmode-original-color-15965526125846="rgb(0, 0, 0)" data-darkmode-bgcolor-15965526125846="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15965526125846="rgb(255, 255, 255)" data-darkmode-bgcolor-15969880239317="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15969880239317="rgb(255, 255, 255)" data-darkmode-color-15969880239317="rgb(163, 163, 163)" data-darkmode-original-color-15969880239317="rgb(0, 0, 0)" data-darkmode-color-15976750929548="rgb(163, 163, 163)" data-darkmode-original-color-15976750929548="rgb(0, 0, 0)" data-darkmode-bgcolor-15976750929548="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15976750929548="rgb(255, 255, 255)" data-darkmode-color-15982803404507="rgb(163, 163, 163)" data-darkmode-original-color-15982803404507="rgb(0, 0, 0)" data-darkmode-bgcolor-15982803404507="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15982803404507="rgb(255, 255, 255)" style="margin-bottom: 20px;white-space: normal;max-width: 100%;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;background-color: rgb(255, 255, 255);color: rgb(0, 0, 0);font-size: 16px;word-spacing: 0.8px;text-align: center;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <span data-darkmode-color-15906764299112="rgb(178, 178, 178)" data-darkmode-original-color-15906764299112="rgb(178, 178, 178)" data-darkmode-bgcolor-15906764299112="rgb(36, 36, 36)" data-darkmode-original-bgcolor-15906764299112="rgb(255, 255, 255)" data-darkmode-color-15958675267961="rgb(163, 163, 163)" data-darkmode-original-color-15958675267961="rgb(178, 178, 178)" data-darkmode-bgcolor-15958675267961="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15958675267961="rgb(255, 255, 255)" data-style="color: rgb(178, 178, 178); font-size: 14px; visibility: visible;" class="js_darkmode__7" data-darkmode-color-15965526125846="rgb(163, 163, 163)" data-darkmode-original-color-15965526125846="rgb(178, 178, 178)" data-darkmode-bgcolor-15965526125846="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15965526125846="rgb(255, 255, 255)" data-darkmode-bgcolor-15969880239317="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15969880239317="rgb(255, 255, 255)" data-darkmode-color-15969880239317="rgb(163, 163, 163)" data-darkmode-original-color-15969880239317="rgb(178, 178, 178)" data-darkmode-color-15976750929548="rgb(163, 163, 163)" data-darkmode-original-color-15976750929548="rgb(178, 178, 178)" data-darkmode-bgcolor-15976750929548="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15976750929548="rgb(255, 255, 255)" data-darkmode-color-15982803404507="rgb(163, 163, 163)" data-darkmode-original-color-15982803404507="rgb(178, 178, 178)" data-darkmode-bgcolor-15982803404507="rgb(25, 25, 25)" data-darkmode-original-bgcolor-15982803404507="rgb(255, 255, 255)" style="max-width: 100%;color: rgb(178, 178, 178);font-size: 14px;visibility: visible;box-sizing: border-box !important;overflow-wrap: break-word !important;">转载请联系授权(微信ID:PassJava)</span> </section> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="font-size: 16px;color: black;padding-right: 10px;padding-left: 10px;line-height: 1.6;letter-spacing: 0px;word-break: break-word;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="margin-bottom: 20px;line-height: 1.8em;color: rgb(58, 58, 58);">上篇我们讲到如何用本地内存:<a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzAwMjI0ODk0NA==&mid=2451954442&idx=1&sn=e5ec784a11fcbad89eb2e4c7a809378d&chksm=8d1c2295ba6bab833b77318661d4aeb4533234f03d4b9e5a298e84b8041258569af4301a21c3&scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">《缓存实战(上篇)》</a> 来做缓存从而增强系统的性能,另外探讨了加锁解决缓存击穿的问题。但是<code style="font-size: 14px;border-radius: 4px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(155, 110, 35);background-color: rgb(255, 245, 227);padding: 3px;margin: 3px;">本地加锁</code>的方式在分布式的场景下就不适用了,所以本文我们来探讨下如何引入<code style="font-size: 14px;border-radius: 4px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(155, 110, 35);background-color: rgb(255, 245, 227);padding: 3px;margin: 3px;">分布式锁</code>解决本地锁的问题。本篇所有代码和业务基于我的开源项目 PassJava。</p> <p data-tool="mdnice编辑器" style="margin-bottom: 20px;line-height: 1.8em;color: rgb(58, 58, 58);">本篇主要内容如下:</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.39223300970873787" src="/upload/efdd7855ea6e014a57352a5ad161eb88.png" data-type="png" data-w="1030" style="margin-right: auto;margin-left: auto;width: 100%;border-radius: 5px;display: block;margin-bottom: 15px;"> </figure> <h2 data-tool="mdnice编辑器" style="font-weight: bold;font-size: 22px;line-height: 1.5em;margin-top: 2.2em;margin-bottom: 35px;"><span style="display: inline-block;background-image: linear-gradient(rgb(255, 255, 255) 60%, rgb(255, 177, 27) 40%);background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;color: rgb(81, 81, 81);padding: 2px 13px;margin-right: 3px;height: 50%;">一、本地锁的问题</span></h2> <p data-tool="mdnice编辑器" style="margin-bottom: 20px;line-height: 1.8em;color: rgb(58, 58, 58);">首先我们来回顾下本地锁的问题:</p> <p data-tool="mdnice编辑器" style="margin-bottom: 20px;line-height: 1.8em;color: rgb(58, 58, 58);">目前题目微服务被拆分成了四个微服务。前端请求进来时,会被转发到不同的微服务。假如前端接收了 10 W 个请求,每个微服务接收 2.5 W 个请求,假如缓存失效了,每个微服务在访问数据库时加锁,通过锁(<code style="font-size: 14px;border-radius: 4px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(155, 110, 35);background-color: rgb(255, 245, 227);padding: 3px;margin: 3px;">synchronzied</code> 或 <code style="font-size: 14px;border-radius: 4px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(155, 110, 35);background-color: rgb(255, 245, 227);padding: 3px;margin: 3px;">lock</code>)来锁住自己的线程资源,从而防止<code style="font-size: 14px;border-radius: 4px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(155, 110, 35);background-color: rgb(255, 245, 227);padding: 3px;margin: 3px;">缓存击穿</code>。</p> <p data-tool="mdnice编辑器" style="margin-bottom: 20px;line-height: 1.8em;color: rgb(58, 58, 58);">这是一种<code style="font-size: 14px;border-radius: 4px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(155, 110, 35);background-color: rgb(255, 245, 227);padding: 3px;margin: 3px;">本地加锁</code>的方式,在<code style="font-size: 14px;border-radius: 4px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(155, 110, 35);background-color: rgb(255, 245, 227);padding: 3px;margin: 3px;">分布式</code>情况下会带来数据不一致的问题:比如服务 A 获取数据后,更新缓存 key =100,服务 B 不受服务 A 的锁限制,并发去更新缓存 key = 99,最后的结果可能是 99 或 100,但这是一种未知的状态,<strong style="color: black;">与期望结果不一致</strong>。流程图如下所示:</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.8600883652430045" src="/upload/b06aee7b8528e5afd1f904d9af9c1917.png" data-type="png" data-w="1358" style="margin-right: auto;margin-left: auto;width: 100%;border-radius: 5px;display: block;margin-bottom: 15px;"> </figure> <h2 data-tool="mdnice编辑器" style="font-weight: bold;font-size: 22px;line-height: 1.5em;margin-top: 2.2em;margin-bottom: 35px;"><span style="display: inline-block;background-image: linear-gradient(rgb(255, 255, 255) 60%, rgb(255, 177, 27) 40%);background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;color: rgb(81, 81, 81);padding: 2px 13px;margin-right: 3px;height: 50%;">二、什么是分布式锁</span></h2> <p data-tool="mdnice编辑器" style="margin-bottom: 20px;line-height: 1.8em;color: rgb(58, 58, 58);">基于上面本地锁的问题,我们需要一种支持<strong style="color: black;">分布式集群环境</strong>下的锁:查询 DB 时,只有一个线程能访问,其他线程都需要等待第一个线程释放锁资源后,才能继续执行。</p> <p data-tool="mdnice编辑器" style="margin-bottom: 20px;line-height: 1.8em;color: rgb(58, 58, 58);"><strong style="color: black;">生活中的案例</strong>:可以把锁看成房门外的一把<code style="font-size: 14px;border-radius: 4px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(155, 110, 35);background-color: rgb(255, 245, 227);padding: 3px;margin: 3px;">锁</code>,所有并发线程比作<code style="font-size: 14px;border-radius: 4px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(155, 110, 35);background-color: rgb(255, 245, 227);padding: 3px;margin: 3px;">人</code>,他们都想进入房间,房间内只能有一个人进入。当有人进入后,将门反锁,其他人必须等待,直到进去的人出来。</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.509212730318258" src="/upload/3d7ce3c6c446e881904ed50a9720a93e.png" data-type="png" data-w="1194" style="margin-right: auto;margin-left: auto;width: 100%;border-radius: 5px;display: block;margin-bottom: 15px;"> </figure> <p data-tool="mdnice编辑器" style="margin-bottom: 20px;line-height: 1.8em;color: rgb(58, 58, 58);">我们来看下分布式锁的基本原理,如下图所示:</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="1.1843220338983051" src="/upload/cf63b1f2de72b93bed4473eab33ede13.png" data-type="png" data-w="944" style="margin-right: auto;margin-left: auto;width: 100%;border-radius: 5px;display: block;margin-bottom: 15px;"> </figure> <p data-tool="mdnice编辑器" style="margin-bottom: 20px;line-height: 1.8em;color: rgb(58, 58, 58);">我们来分析下上图的分布式锁:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-2"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 1.前端将 10W 的高并发请求转发给四个题目微服务。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 2.每个微服务处理 2.5 W 个请求。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 3.每个处理请求的线程在执行业务之前,需要先抢占锁。可以理解为“占坑”。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 4.获取到锁的线程在执行完业务后,释放锁。可以理解为“释放坑位”。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 5.未获取到的线程需要等待锁释放。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 6.释放锁后,其他线程抢占锁。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 7.重复执行步骤 4、5、6。 </section></li> </ul> <p data-tool="mdnice编辑器" style="margin-bottom: 20px;line-height: 1.8em;color: rgb(58, 58, 58);">大白话解释:所有请求的线程都去同一个地方<code style="font-size: 14px;border-radius: 4px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(155, 110, 35);background-color: rgb(255, 245, 227);padding: 3px;margin: 3px;">“占坑”</code>,如果有坑位,就执行业务逻辑,没有坑位,就需要其他线程释放“坑位”。这个坑位是所有线程可见的,可以把这个坑位放到 Redis 缓存或者数据库,这篇讲的就是如何用 Redis 做<code style="font-size: 14px;border-radius: 4px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(155, 110, 35);background-color: rgb(255, 245, 227);padding: 3px;margin: 3px;">“分布式坑位”</code>。</p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;font-size: 22px;line-height: 1.5em;margin-top: 2.2em;margin-bottom: 35px;"><span style="display: inline-block;background-image: linear-gradient(rgb(255, 255, 255) 60%, rgb(255, 177, 27) 40%);background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;color: rgb(81, 81, 81);padding: 2px 13px;margin-right: 3px;height: 50%;">三、Redis 的 SETNX</span></h2> <p data-tool="mdnice编辑器" style="margin-bottom: 20px;line-height: 1.8em;color: rgb(58, 58, 58);">Redis 作为一个公共可访问的地方,正好可以作为“占坑”的地方。</p> <p data-tool="mdnice编辑器" style="margin-bottom: 20px;line-height: 1.8em;color: rgb(58, 58, 58);">用 Redis 实现分布式锁的几种方案,我们都是用 SETNX 命令(设置 key 等于某 value)。只是高阶方案传的参数个数不一样,以及考虑了异常情况。</p> <p data-tool="mdnice编辑器" style="margin-bottom: 20px;line-height: 1.8em;color: rgb(58, 58, 58);">我们来看下这个命令,<code style="font-size: 14px;border-radius: 4px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(155, 110, 35);background-color: rgb(255, 245, 227);padding: 3px;margin: 3px;">SETNX</code>是<code style="font-size: 14px;border-radius: 4px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(155, 110, 35);background-color: rgb(255, 245, 227);padding: 3px;margin: 3px;">set If not exist</code>的简写。意思就是当 k