作者:微信小助手
<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;margin-top: -10px;line-height: 1.6;letter-spacing: 0.034em;color: rgb(63, 63, 63);font-size: 16px;"> <blockquote data-tool="mdnice编辑器" style="font-size: 0.9em;overflow: auto;background: rgb(251, 249, 253);color: rgb(106, 115, 125);margin-bottom: 20px;margin-top: 20px;padding: 15px 20px;line-height: 27px;border-left-color: rgb(53, 179, 120);"> <p style="line-height: 26px;font-size: 15px;color: rgb(89, 89, 89);">作者:_release<br>原文地址:https://juejin.im/post/5ed37a73e51d45788c739784</p> </blockquote> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 22px;text-align: center;background-image: url("https://mmbiz.qpic.cn/mmbiz_png/YBFV3Da0NwssYBkz7fpPSW2M2IwX8ImiaUrqYGhAAKUjlicm4IshTJCah4aqPvXs4lQbq0ibzJLicy2pAuEwEWPBoA/640?wx_fmt=png");background-position: center center;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;background-size: 50px;margin-top: 1em;margin-bottom: 10px;"><span style="display: none;"></span><span style="display: inline-block;height: 38px;line-height: 42px;color: rgb(72, 179, 120);background-position: left center;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;background-size: 63px;margin-top: 38px;font-size: 18px;margin-bottom: 10px;">前言</span></h2> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">闲着没事,就想着写写原生js玩玩,在网上看了几个效果后决定做这个效果,并且使用了prototype和eventEmitter封装成了库。</p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 22px;text-align: center;background-image: url("https://mmbiz.qpic.cn/mmbiz_png/YBFV3Da0NwssYBkz7fpPSW2M2IwX8ImiaUrqYGhAAKUjlicm4IshTJCah4aqPvXs4lQbq0ibzJLicy2pAuEwEWPBoA/640?wx_fmt=png");background-position: center center;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;background-size: 50px;margin-top: 1em;margin-bottom: 10px;"><span style="display: none;"></span><span style="display: inline-block;height: 38px;line-height: 42px;color: rgb(72, 179, 120);background-position: left center;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;background-size: 63px;margin-top: 38px;font-size: 18px;margin-bottom: 10px;">最终效果</span></h2> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;"> <img data-ratio="0.11160220994475138" src="/upload/90a6cd0e16e62a9fa052eddc3e9f6efe.gif" data-type="gif" data-w="905" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> </figure> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 22px;text-align: center;background-image: url("https://mmbiz.qpic.cn/mmbiz_png/YBFV3Da0NwssYBkz7fpPSW2M2IwX8ImiaUrqYGhAAKUjlicm4IshTJCah4aqPvXs4lQbq0ibzJLicy2pAuEwEWPBoA/640?wx_fmt=png");background-position: center center;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;background-size: 50px;margin-top: 1em;margin-bottom: 10px;"><span style="display: none;"></span><span style="display: inline-block;height: 38px;line-height: 42px;color: rgb(72, 179, 120);background-position: left center;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;background-size: 63px;margin-top: 38px;font-size: 18px;margin-bottom: 10px;">分析</span></h2> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">看到这个效果我们首先应该想到和拖动有关的api: onmousedown, onmousemove, onmouseup</p> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">其次要支持用户传入放置这个组件的dom元素和完成的回调事件。</p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 22px;text-align: center;background-image: url("https://mmbiz.qpic.cn/mmbiz_png/YBFV3Da0NwssYBkz7fpPSW2M2IwX8ImiaUrqYGhAAKUjlicm4IshTJCah4aqPvXs4lQbq0ibzJLicy2pAuEwEWPBoA/640?wx_fmt=png");background-position: center center;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;background-size: 50px;margin-top: 1em;margin-bottom: 10px;"><span style="display: none;"></span><span style="display: inline-block;height: 38px;line-height: 42px;color: rgb(72, 179, 120);background-position: left center;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;background-size: 63px;margin-top: 38px;font-size: 18px;margin-bottom: 10px;">最终如何使用?</span></h2> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">我们先来看下使用方式,再来决定我们怎么编写这个库</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;"> <img data-ratio="0.5162213740458015" src="/upload/7892ed7d7188a63a56b75ee31a8dd2cc.png" data-type="png" data-w="1048" style="display: block;margin-right: auto;margin-left: auto;border-radius: 4px;margin-bottom: 25px;"> </figure> <p data-tool="mdnice编辑器" style="padding-bottom: 8px;padding-top: 1em;color: rgb(74, 74, 74);line-height: 1.75em;">具体使用就是这样的,我们还想用户能通过import等方式使用,所以我们就要支持esMoudule的导入方式。</p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 22px;text-align: center;background-image: url("https://mmbiz.qpic.cn/mmbiz_png/YBFV3Da0NwssYBkz7fpPSW2M2IwX8ImiaUrqYGhAAKUjlicm4IshTJCah4aqPvXs4lQbq0ibzJLicy2pAuEwEWPBoA/640?wx_fmt=png");background-position: center center;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;background-size: 50px;margin-top: 1em;margin-bottom: 10px;"><span style="display: none;"></span><span style="display: inline-block;height: 38px;line-height: 42px;color: rgb(72, 179, 120);background-position: left center;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;background-size: 63px;margin-top: 38px;font-size: 18px;margin-bottom: 10px;">编写库的整体初始框架</span></h2> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;color: #333;background: #f8f8f8;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;">(<span style="line-height: 26px;"><span style="font-weight: bold;line-height: 26px;">function</span> (<span style="line-height: 26px;"></span>) </span>{<br> <span style="color: #998;font-style: italic;line-height: 26px;">// =================代码块1=========================================</span><br> <span style="font-weight: bold;line-height: 26px;">var</span> root = (<span style="font-weight: bold;line-height: 26px;">typeof</span> self == <span style="color: #d14;line-height: 26px;">'object'</span> && self.self == self && self) ||<br> (<span style="font-weight: bold;line-height: 26px;">typeof</span> global == <span style="color: #d14;line-height: 26px;">'object'</span> && global.global == global && global) ||<br> <span style="font-weight: bold;line-height: 26px;">this</span> || {}; <br> <span style="font-weight: bold;line-height: 26px;">var</span> util = {<br> <span style="line-height: 26px;">extend</span>: <span style="line-height: 26px;"><span style="font-weight: bold;line-height: 26px;">function</span> (<span style="line-height: 26px;">target</span>) </span>{<br> <span style="font-weight: bold;line-height: 26px;">for</span> (<span style="font-weight: bold;line-height: 26px;">var</span> i = <span style="color: #008080;line-height: 26px;">1</span>, len = <span style="color: #0086b3;line-height: 26px;">arguments</span>.length; i < len; i++) {<br> <span style="font-weight: bold;line-height: 26px;">for</span> (<span style="font-weight: bold;line-height: 26px;">var</span> prop <span style="font-weight: bold;line-height: 26px;">in</span> <span style="color: #0086b3;line-height: 26px;">arguments</span>[i]) {<br> <span style="font-weight: bold;line-height: 26px;">if</span> (<span style="color: #0086b3;line-height: 26px;">arguments</span>[i].hasOwnProperty(prop)) {<br> target[prop] = <span style="color: #0086b3;line-height: 26px;">arguments</span>[i][prop]<br> }<br> }<br> }<br> <span style="font-weight: bold;line-height: 26px;">return</span> target<br> },<br> <span style="line-height: 26px;">isValidListener</span>: <span style="line-height: 26px;"><span style="font-weight: bold;line-height: 26px;">function</span> (<span style="line-height: 26px;">listener</span>) </span>{<br> <span style="font-weight: bold;line-height: 26px;">if</span> (<span style="font-weight: bold;line-height: 26px;">typeof</span> listener === <span style="color: #d14;line-height: 26px;">'function'</span>) {<br> <span style="font-weight: bold;line-height: 26px;">return</span> <span style="color: #008080;line-height: 26px;">true</span><br> } <span style="font-weight: bold;line-height: 26px;">else</span> <span style="font-weight: bold;line-height: 26px;">if</span> (listener && <span style="font-weight: bold;line-height: 26px;">typeof</span> listener === <span style="color: #d14;line-height: 26px;">'object'</span>) {<br> <span style="font-weight: bold;line-height: 26px;">return</span> util.isValidListener(listener.listener)<br> } <span style="font-weight: bold;line-height: 26px;">else</span> {<br> <span style="font-weight: bold;line-height: 26px;">return</span> <span style="color: #008080;line-height: 26px;">false</span><br> }<br> },<br> <span style="line-height: 26px;">addCSS</span>: <span style="line-height: 26px;"><span style="font-weight: bold;line-height: 26px;">function</span> (<span style="line-height: 26px;">cssText</span>) </span>{<br> <span style="font-weight: bold;line-height: 26px;">var</span> style = <span style="color: #0086b3;line-height: 26px;">document</span>.createElement(<span style="color: #d14;line-height: 26px;">'style'</span>), <span style="color: #998;font-style: italic;line-height: 26px;">//创建一个style元素</span><br> head = <span style="color: #0086b3;line-height: 26px;">document</span>.head || <span style="color: #0086b3;line-height: 26px;">document</span>.getElementsByTagName(<span style="color: #d14;line-height: 26px;">'head'</span>)[<span style="color: #008080;line-height: 26px;">0</span>]; <span style="color: #998;font-style: italic;line-height: 26px;">//获取head元素</span><br> style.type = <span style="color: #d14;line-height: 26px;">'text/css'</span>; <span style="color: #998;font-style: italic;line-height: 26px;">//这里必须显示设置style元素的type属性为text/css,否则在ie中不起作用</span><br> <span style="font-weight: bold;line-height: 26px;">if</span> (style.styleSheet) { <span style="color: #998;font-style: italic;line-height: 26px;">//IE</span><br> <span style="font-weight: bold;line-height: 26px;">var</span> func = <span style="line-height: 26px;"><span style="font-weight: bold;line-height: 26px;">function</span> (<span style="line-height: 26px;"></span>) </span>{<br> <span style="font-weight: bold;line-height: 26px;">try</span> { <span style="color: #998;font-style: italic;line-height: 26px;">//防止IE中stylesheet数量超过限制而发生错误</span><br> style.styleSheet.cssText = cssText;<br> } <span style="font-weight: bold;line-height: 26px;">catch</span> (e) {<br><br> }<br> }<br> <span style="color: #998;font-style: italic;line-height: 26px;">//如果当前styleSheet还不能用,则放到异步中则行</span><br> <span style="font-weight: bold;line-height: 26px;">if</span> (style.styleSheet.disabled) {<br> setTimeout(func, <span style="color: #008080;line-height: 26px;">10</span>);<br> } <span style="font-weight: bold;line-height: 26px;">else</span> {<br> func();<br> }<br> } <span style="font-weight: bold;line-height: 26px;">else</span> { <span style="color: #998;font-style: italic;line-height: 26px;">//w3c</span><br> <span style="color: #998;font-style: italic;line-height: 26px;">//w3c浏览器中只要创建文本节点插入到style元素中就行了</span><br> <span style="font-weight: bold;line-height: 26px;">var</span> textNode = <span style="color: #0086b3;line-height: 26px;">document</span>.createTextNode(cssText);<br> style.appendChild(textNode);<br> }<br> head.appendChild(style); <span style="color: #998;font-style: italic;line-height: 26px;">//把创建的style元素插入到head中</span><br> },<br> <span style="line-height: 26px;">indexOf</span>: <span style="line-height: 26px;"><span style="font-weight: bold;line-height: 26px;">function</span> (<span style="line-height: 26px;">array, item</span>) </span>{<br> <span style="font-weight: bold;line-height: 26px;">if</span> (array.indexOf) {<br> <span style="font-weight: bold;line-height: 26px;">return</span> array.indexOf(item);<br> } <span style="font-weight: bold;line-height: 26px;">else</span> {<br> <span style="font-weight: bold;line-height: 26px;">var</span> result = <span style="color: #008080;line-height: 26px;">-1</span>;<br> <span style="font-weight: bold;line-height: 26px;">for</span> (<span style="font-weight: bold;line-height: 26px;">var</span> i = <span style="color: #008080;line-height: 26px;">0</span>, len = array.length; i < len; i++) {<br> <span style="font-weight: bold;line-height: 26px;">if</span> (array[i] === item) {<br> result = i;<br> <span style="font-weight: bold;line-height: 26px;">break</span>;<br> }<br> }<br> <span style="font-weight: bold;line-height: 26px;">return</span> result;<br> }<br> }<br> }<br> <br> <span style="line-height: 26px;"><span style="font-weight: bold;line-height: 26px;">function</span> <span style="color: #900;font-weight: bold;line-height: 26px;">EventEmitter</span>(<span style="line-height: 26px;"></span>) </span>{<br> <span style="font-weight: bold;line-height: 26px;">this</span>._events = {}<br> }<br><br> EventEmitter.prototype.on = <span style="line-height: 26px;"><span style="font-weight: bold;line-height: 26px;">function</span> (<span style="line-height: 26px;">eventName, listener</span>) </span>{<br> <span style="font-weight: bold;line-height: 26px;">if</span> (!eventName || !listener) <span style="font-weight: bold;line-height: 26px;">return</span>;<br> <span style="font-weight: bold;line-height: 26px;">if</span> (!util.isValidListener(listener)) {<br> <span style="font-weight: bold;line-height: 26px;">throw</span> <span style="font-weight: bold;line-height: 26px;">new</span> <span style="color: #0086b3;line-height: 26px;">TypeError</span>(<span style="color: #d14;line-height: 26px;">'listener must be a function'</span>);<br> }<br> <span style="font-weight: bold;line-height: 26px;">var</span> events = <span style="font-weight: bold;line-height: 26px;">this</span>._events;<br> <span style="font-weight: bold;line-height: 26px;">var</span> listeners = events[eventName] = events[eventName] || [];<br> <span style="font-weight: bold;line-height: 26px;">var</span> listenerIsWrapped = <span style="font-weight: bold;line-height: 26px;">typeof</span> listener === <span style="color: #d14;line-height: 26px;">'object'</span>;<br> <span style="color: #998;font-style: italic;line-height: 26px;">// 不重复添加事件</span><br> <span style="font-weight: bold;line-height: 26px;">if</span> (util.indexOf(listeners, listener) === <span style="color: #008080;line-height: 26px;">-1</span>) {<br> listeners.push(listenerIsWrapped ? listener : {<br> <span style="line-height: 26px;">listener</span>: listener,<br> <span style="line-height: 26px;">once</span>: <span style="color: #008080;line-height: 26px;">false</span><br> });<br> }<br> <span style="font-weight: bold;line-height: 26px;">return</span> <span style="font-weight: bold;line-height: 26px;">this</span>;<br> };<br> EventEmitter.prototype.once = <span style="line-height: 26px;"><span style="font-weight: bold;line-height: 26px;">function</span> (<span style="line-height: 26px;">eventName, listener</span>) </span>{<br> <span style="font-weight: bold;line-height: 26px;">return</span> <span style="font-weight: bold;line-height: 26px;">this</span>.on(eventName, {<br> <span style="line-height: 26px;">listener</span>: listener,<br> <span style="line-height: 26px;">once</span>: <span style="color: #008080;line-height: 26px;">true</span><br> })<br> };<br> EventEmitter.prototype.off = <span style="line-height: 26px;"><span style="font-weight: bold;line-height: 26px;">function</span> (<span style="line-height: 26px;">eventName, listener</span>) </span>{<br> <span style="font-weight: bold;line-height: 26px;">var</span> listeners = <span style="font-weight: bold;line-height: 26px;">this</span>._events[eventName];<br> <span style="font-weight: bold;line-height: 26px;">if</span> (!listeners) <span style="font-weight: bold;line-height: 26px;">return</span>;<br> <span style="font-weight: bold;line-height: 26px;">var</span> index;<br> <span style="font-weight: bold;line-height: 26px;">for</span> (<span style="font-weight: bold;line-height: 26px;">var</span> i = <span style="color: #008080;line-height: 26px;">0</span>, len = listeners.length; i < len; i++) {<br> <span style="font-weight: bold;line-height: 26px;">if</span> (listeners[i] && listeners[i].listener === listener) {<br> index = i;<br> <span style="font-weight: bold;line-height: 26px;">break</span>;<br> }<br> }<br> <span style="font-weight: bold;line-height: 26px;">if</span> (<span style="font-weight: bold;line-height: 26px;">typeof</span> index !== <span style="color: #d14;line-height: 26px;">'undefined'</span>) {<br> listeners.splice(index, <span style="color: #008080;line-height: 26px;">1</span>, <span style="color: #008080;line-height: 26px;">null</span>)<br> }<br> <span style="font-weight: bold;line-height: 26px;">return</span> <span style="font-weight: bold;line-height: 26px;">this</span>;<br> };<br> EventEmitter.prototype.emit = <span style="line-height: 26px;"><span style="font-weight: bold;line-height: 26px;">function</span> (<span style="line-height: 26px;">eventName, args</span>) </span>{<br> <span style="font-weight: bold;line-height: 26px;">var</span> listeners = <span style="font-weight: bold;line-height: 26px;">this</span>._events[eventName];<br> <span style="font-weight: bold;line-height: 26px;">if</span> (!listeners) <span style="font-weight: bold;line-height: 26px;">return</span>;<br> <span style="font-weight: bold;line-height: 26px;">for</span> (<span style="font-weight: bold;line-height: 26px;">var</span> i = <span style="color: #008080;line-height: 26px;">0</span>; i < listeners.length; i++) {<br> <span style="font-weight: bold;line-height: 26px;">var</span> listener = listeners[i];<br> <span style="font-weight: bold;line-height: 26px;">if</span> (listener) {<br> listener.listener.apply(<span style="font-weight: bold;line-height: 26px;">this</span>, args || []);<br> <span style="font-weight: bold;line-height: 26px;">if</span> (listener.once) {<br> <span style="font-weight: bold;line-height: 26px;">this</span>.off(eventName, listener.listener)<br> }<br> }<br> }<br> <span style="font-weight: bold;line-height: 26px;">return</span> <span style="font-weight: bold;line-height: 26px;">this</span>;<br> };<br> <br> <span style="color: #998;font-style: italic;line-height: 26px;">// =================代码块2=========================================</span><br> <span style="line-height: 26px;"><span style="font-weight: bold;line-height: 26px;">function</span> <span style="color: #900;font-weight: bold;line-height: 26px;">SliderTools</span>(<span style="line-height: 26px;">options</span>) </span>{<br> <span style="font-weight: bold;line-height: 26px;">this</span>.options = util.extend({}, <span style="font-weight: bold;line-height: 26px;">this</span>.constructor.defaultOptions, options)<br> <span style="font-weight: bold;line-height: 26px;">this</span>.init();<br> <span style="font-weight: bold;line-height: 26px;">this</span>.bindEvents();<br> <span style="font-weight: bold;line-height: 26px;">this</span>.diffX = <span style="color: #008080;line-height: 26px;">0</span>;<br> <span style="font-weight: bold;line-height: 26px;">this</span>.flag = <span style="color: #008080;line-height: 26px;">false</span>;<span style="color: #998;font-style: italic;line-height: 26px;">//是否拖动到最右侧</span><br> }<br><br> SliderTools.defaultOptions = {<br> <span style="line-height: 26px;">el</span>: <span style="color: #0086b3;line-height: 26px;">document</span>.body <span style="color: #998;font-style: italic;line-height: 26px;">//默认放到body里</span><br> };<br> <br> <span style="font-weight: bold;line-height: 26px;">var</span> proto = SliderTools.prototype = <span style="font-weight: bold;line-height: 26px;">new</span> EventEmitter();<span style="color: #998;font-style: italic;line-height: 26px;">//SliderTools继承emitter</span><br> <br> proto.constructor = SliderTools;<span style="color: #998;font-style: italic;line-height: 26px;">//修正构造器</span><br><br> proto.init = <span style="line-height: 26px;"><span style="font-weight: bold;line-height: 26px;">function</span> (<span style="line-height: 26px;"></span>) </span>{<br> <span style="font-weight: bold;line-height: 26px;">this</span>.createSlider();<span style="color: #998;font-style: italic;line-height: 26px;">//创建插件所需要的dom元素</span><br> <span style="font-weight: bold;line-height: 26px;">this</span>.getElements();<span style="color: #998;font-style: italic;line-height: 26px;">//获取创建好的元素</span><br> }<br>
作者:微信小助手
<p 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;white-space: normal;color: rgb(0, 0, 0);font-size: medium;background-color: rgb(255, 255, 255);text-align: center;word-break: normal !important;" data-mpa-powered-by="yiban.io"><span style="font-size: 13px;color: rgb(136, 136, 136);font-family: Georgia, "Times New Roman", Times, "Songti SC", serif;letter-spacing: 0.544px;word-break: normal !important;">点击上方蓝色“</span><span style="font-size: 13px;font-family: Georgia, "Times New Roman", Times, "Songti SC", serif;letter-spacing: 0.544px;color: rgb(0, 128, 255);word-break: normal !important;">码农架构</span><span style="font-size: 13px;color: rgb(136, 136, 136);font-family: Georgia, "Times New Roman", Times, "Songti SC", serif;letter-spacing: 0.544px;word-break: normal !important;">”,选择“设为星标”</span><strong style="letter-spacing: 0.544px;color: rgb(74, 74, 74);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;font-size: 16px;white-space: pre-line;text-align: right;word-break: normal !important;"></strong></p> <p 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;white-space: normal;color: rgb(0, 0, 0);font-size: medium;background-color: rgb(255, 255, 255);text-align: center;word-break: normal !important;"><span style="font-size: 13px;color: rgb(136, 136, 136);font-family: Georgia, "Times New Roman", Times, "Songti SC", serif;letter-spacing: 0.544px;word-break: normal !important;">专注于高可用、高性能、高并发类技术分享!</span></p> <p style="margin-top: 5px;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;white-space: normal;color: rgb(0, 0, 0);font-size: medium;text-align: left;background-color: rgb(255, 255, 255);word-break: normal !important;"><img data-ratio="0.0625" data-w="640" data-type="png" src="/upload/f378fd8bc917b4aec1204ea03d12894c.png" style="box-sizing: border-box !important;word-break: normal !important;visibility: visible !important;width: 640px !important;"></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">对于List 集合类,我想大家肯定很了解了,那我想一定也知道集合的顶端接口 Collection。在 Java8 中,Collection 新增了两个流方法,分别是 Stream() 和 parallelStream()</span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">通过英文名不难猜测,这两个方法肯定和 Stream 有关,那进一步猜测,是不是和我们熟悉的 InputStream 和 OutputStream 也有关系呢?集合类中新增的两个 Stream 方法到底有什么作用?</span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;"><strong><span style="font-size: 18px;">什么是 Stream?</span></strong></span></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">在 Java8 之前,我们通常是通过 for 循环或者 Iterator 迭代来重新排序合并数据,又或者通过重新定义 Collections.sorts 的 Comparator 方法来实现,这两种方式对于大数据量系统来说,效率并不是很理想。</span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">Java8 中添加了一个新的接口类 Stream,他和我们之前接触的字节流概念不太一样,Java8 集合中的 Stream 相当于高级版的 Iterator,他可以通过 Lambda 表达式对集合进行各种非常便利、高效的聚合操作(Aggregate Operation),或者大批量数据操作 (Bulk Data Operation)。</span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">Stream 的聚合操作与数据库 SQL 的聚合操作 sorted、filter、map 等类似。我们在应用层就可以高效地实现类似数据库 SQL 的聚合操作了,而在数据操作方面,Stream 不仅可以通过串行的方式实现数据操作,还可以通过并行的方式处理大批量数据,提高数据的处理效率。</span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;"><strong>接下来我们就用一个简单的例子来体验下 Stream 的简洁与强大。</strong></span></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">这个 Demo 的需求是过滤分组一所中学里身高在 160cm 以上的男女同学,我们先用传统的迭代方式来实现,代码如下:</span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="php"><code><span class="code-snippet_outer">Map<String, <span class="code-snippet__keyword">List</span><Student>> stuMap = <span class="code-snippet__keyword">new</span> HashMap<String, <span class="code-snippet__keyword">List</span><Student>>();</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">for</span> (Student stu: studentsList) {</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">if</span> (stu.getHeight() > <span class="code-snippet__number">160</span>) { <span class="code-snippet__comment">//如果身高大于160</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">if</span> (stuMap.get(stu.getSex()) == <span class="code-snippet__keyword">null</span>) { <span class="code-snippet__comment">//该性别还没分类</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">List</span><Student> <span class="code-snippet__keyword">list</span> = <span class="code-snippet__keyword">new</span> ArrayList<Student>(); <span class="code-snippet__comment">//新建该性别学生的列表</span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">list</span>.add(stu);<span class="code-snippet__comment">//将学生放进去列表</span></span></code><code><span class="code-snippet_outer"> stuMap.put(stu.getSex(), <span class="code-snippet__keyword">list</span>);<span class="code-snippet__comment">//将列表放到map中</span></span></code><code><span class="code-snippet_outer"> } <span class="code-snippet__keyword">else</span> { <span class="code-snippet__comment">//该性别分类已存在</span></span></code><code><span class="code-snippet_outer"> stuMap.get(stu.getSex()).add(stu);<span class="code-snippet__comment">//该性别分类已存在,则直接放进去即可</span></span></code><code><span class="code-snippet_outer"> }</span></code><code><span class="code-snippet_outer"> }</span></code><code><span class="code-snippet_outer"> }</span></code></pre> </section> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;"></span><br></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">我们再使用 Java8 中的 Stream API 进行实现:</span></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">1. 串行实现</span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="ruby"><code><span class="code-snippet_outer">Map<String, List<Student<span class="code-snippet__meta">>> </span>stuMap = stuList.stream().filter((Student s) -> s.getHeight() > <span class="code-snippet__number">160</span>) .collect(Collectors.groupingBy(Student <span class="code-snippet__symbol">:</span><span class="code-snippet__symbol">:getSex</span>));</span></code></pre> </section> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">2. 并行实现</span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="ruby"><code><span class="code-snippet_outer">Map<String, List<Student<span class="code-snippet__meta">>> </span>stuMap = stuList.parallelStream().filter((Student s) -> s.getHeight() > <span class="code-snippet__number">160</span>) .collect(Collectors.groupingBy(Student <span class="code-snippet__symbol">:</span><span class="code-snippet__symbol">:getSex</span>));</span></code></pre> </section> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">通过上面两个简单的例子,我们可以发现,Stream 结合 Lambda 表达式实现遍历筛选功能非常得简洁和便捷。</span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;"><span style="font-size: 18px;"><strong>Stream 如何优化遍历?</strong></span></span></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">上面我们初步了解了 Java8 中的 Stream API,那 Stream 是如何做到优化迭代的呢?并行又是如何实现的?下面我们就透过 Stream 源码剖析 Stream 的实现原理。</span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;"><strong>1.Stream 操作分类</strong></span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">官方将 Stream 中的操作分为两大类:<strong>中间操作(Intermediate operations)和终结操作(Terminal operations)</strong>。中间操作只对操作进行了记录,即只会返回一个流,不会进行计算操作,而终结操作是实现了计算操作。</span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;"><strong>终结操作又可以分为短路(Short-circuiting)与非短路(Unshort-circuiting)</strong>操作,前者是指遇到某些符合条件的元素就可以得到最终结果,后者是指必须处理完所有元素才能得到最终结果。操作分类详情如下图所示:</span></p> <p><span style="font-size: 16px;font-family: "PingFang SC";"><img data-ratio="0.706286836935167" src="/upload/4c3c30c444881a037255c87f3ee56f0.jpg" data-type="jpeg" data-w="2036"></span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;"><span style="color:#FF9300;">我们通常还会将中间操作称为懒操作,也正是由这种懒操作结合终结操作、数据源构成的处理管道(Pipeline),实现了 Stream 的高效。</span></span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;"><strong>2.Stream 源码实现</strong></span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">在了解 Stream 如何工作之前,我们先来了解下 Stream 包是由哪些主要结构类组合而成的,各个类的职责是什么。参照下图:</span></p> <p><span style="font-size: 16px;font-family: "PingFang SC";"><img data-ratio="0.6131805157593123" src="/upload/5482b34e4c3ee51bfb7b899bd6259bb3.jpg" data-type="jpeg" data-w="698"></span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">BaseStream 和 Stream 为最顶端的接口类。BaseStream 主要定义了流的基本接口方法,例如,spliterator、isParallel 等;Stream 则定义了一些流的常用操作方法,例如,map、filter 等。</span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">ReferencePipeline 是一个结构类,他通过定义内部类组装了各种操作流。他定义了 Head、StatelessOp、StatefulOp 三个内部类,实现了 BaseStream 与 Stream 的接口方法。</span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">Sink 接口是定义每个 Stream 操作之间关系的协议,他包含 begin()、end()、cancellationRequested()、accpt() 四个方法。ReferencePipeline 最终会将整个 Stream 流操作组装成一个调用链,而这条调用链上的各个 Stream 操作的上下关系就是通过 Sink 接口协议来定义实现的。</span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;"><strong>3.Stream 操作叠加</strong></span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">我们知道,一个 Stream 的各个操作是由处理管道组装,并统一完成数据处理的。在 JDK 中每次的中断操作会以使用阶段(Stage)命名。</span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">管道结构通常是由 ReferencePipeline 类实现的,前面讲解 Stream 包结构时,我提到过 ReferencePipeline 包含了 Head、StatelessOp、StatefulOp 三种内部类。</span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">Head 类主要用来定义数据源操作,在我们初次调用 names.stream() 方法时,会初次加载 Head 对象,此时为加载数据源操作;接着加载的是中间操作,分别为无状态中间操作 StatelessOp 对象和有状态操作 StatefulOp 对象,此时的 Stage 并没有执行,而是通过 AbstractPipeline 生成了一个中间操作 Stage 链表;当我们调用终结操作时,会生成一个最终的 Stage,通过这个 Stage 触发之前的中间操作,从最后一个 Stage 开始,递归产生一个 Sink 链。如下图所示:</span></p> <p><span style="font-size: 16px;font-family: "PingFang SC";"><img data-ratio="0.19633225458468176" src="/upload/82e1a89e982c4619b23b032b07c4713d.jpg" data-type="jpeg" data-w="1854"></span></p> <p><br></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="swift"><code><span class="code-snippet_outer"><span class="code-snippet__type">List</span><<span class="code-snippet__type">String</span>> names = <span class="code-snippet__type">Arrays</span>.asList(<span class="code-snippet__string">"张三"</span>, <span class="code-snippet__string">"李四"</span>, <span class="code-snippet__string">"王老五"</span>, <span class="code-snippet__string">"李三"</span>, <span class="code-snippet__string">"刘老四"</span>, <span class="code-snippet__string">"王小二"</span>, <span class="code-snippet__string">"张四"</span>, <span class="code-snippet__string">"张五六七"</span>);</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"><span class="code-snippet__type">String</span> maxLenStartWithZ = names.stream()</span></code><code><span class="code-snippet_outer"> .<span class="code-snippet__built_in">filter</span>(name -> name.<span class="code-snippet__built_in">startsWith</span>(<span class="code-snippet__string">"张"</span>))</span></code><code><span class="code-snippet_outer"> .mapToInt(<span class="code-snippet__type">String</span>::length)</span></code><code><span class="code-snippet_outer"> .<span class="code-snippet__built_in">max</span>()</span></code><code><span class="code-snippet_outer"> .<span class="code-snippet__built_in">toString</span>();</span></code></pre> </section> <p><br></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">这个例子的需求是查找出一个长度最长,并且以张为姓氏的名字。从代码角度来看,你可能会认为是这样的操作流程:首先遍历一次集合,得到以“张”开头的所有名字;然后遍历一次 filter 得到的集合,将名字转换成数字长度;最后再从长度集合中找到最长的那个名字并且返回。</span></p> <p><br></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;"><strong>4.Stream 并行处理</strong></span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">Stream 处理数据的方式有两种,串行处理和并行处理。要实现并行处理,我们只需要在例子的代码中新增一个 Parallel() 方法,代码如下所示:</span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="swift"><code><span class="code-snippet_outer"><span class="code-snippet__type">List</span><<span class="code-snippet__type">String</span>> names = <span class="code-snippet__type">Arrays</span>.asList(<span class="code-snippet__string">"张三"</span>, <span class="code-snippet__string">"李四"</span>, <span class="code-snippet__string">"王老五"</span>, <span class="code-snippet__string">"李三"</span>, <span class="code-snippet__string">"刘老四"</span>, <span class="code-snippet__string">"王小二"</span>, <span class="code-snippet__string">"张四"</span>, <span class="code-snippet__string">"张五六七"</span>);</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"><span class="code-snippet__type">String</span> maxLenStartWithZ = names.stream()</span></code><code><span class="code-snippet_outer"> .parallel()</span></code><code><span class="code-snippet_outer"> .<span class="code-snippet__built_in">filter</span>(name -> name.<span class="code-snippet__built_in">startsWith</span>(<span class="code-snippet__string">"张"</span>))</span></code><code><span class="code-snippet_outer"> .mapToInt(<span class="code-snippet__type">String</span>::length)</span></code><code><span class="code-snippet_outer"> .<span class="code-snippet__built_in">max</span>()</span></code><code><span class="code-snippet_outer"> .<span class="code-snippet__built_in">toString</span>();</span></code></pre> </section> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">Stream 的并行处理在执行终结操作之前,跟串行处理的实现是一样的。而在调用终结方法之后,实现的方式就有点不太一样,会调用 TerminalOp 的 evaluateParallel 方法进行并行处理。</span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="java"><code><span class="code-snippet_outer"><span class="code-snippet__keyword">final</span> <R> <span class="code-snippet__function">R <span class="code-snippet__title">evaluate</span><span class="code-snippet__params">(TerminalOp<E_OUT, R> terminalOp)</span> </span>{</span></code><code><span class="code-snippet_outer"><br></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__function"><span class="code-snippet__keyword">assert</span> <span class="code-snippet__title">getOutputShape</span><span class="code-snippet__params">()</span> </span>== terminalOp.inputShape();</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">if</span> (linkedOrConsumed)</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">throw</span> <span class="code-snippet__keyword">new</span> IllegalStateException(MSG_STREAM_LINKED);</span></code><code><span class="code-snippet_outer"> linkedOrConsumed = <span class="code-snippet__keyword">true</span>;</span></code><code><span class="code-snippet_outer"> <span class="code-snippet__keyword">return</span> isParallel()</span></code><code><span class="code-snippet_outer"> ? terminalOp.evaluateParallel(<span class="code-snippet__keyword">this</span>, sourceSpliterator(terminalOp.getOpFlags()))</span></code><code><span class="code-snippet_outer"> : terminalOp.evaluateSequential(<span class="code-snippet__keyword">this</span>, sourceSpliterator(terminalOp.getOpFlags()));</span></code><code><span class="code-snippet_outer"> }</span></code></pre> </section> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">这里的并行处理指的是,Stream 结合了 ForkJoin 框架,对 Stream 处理进行了分片,Splititerator 中的 estimateSize 方法会估算出分片的数据量。</span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;"><strong>总结</strong></span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">纵观 Stream 的设计实现,非常值得我们学习。从大的设计方向上来说,Stream 将整个操作分解为了链式结构,不仅简化了遍历操作,还为实现了并行计算打下了基础</span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;">从小的分类方向上来说,Stream 将遍历元素的操作和对元素的计算分为中间操作和终结操作,而中间操作又根据元素之间状态有无干扰分为有状态和无状态操作,实现了链结构中的不同阶段。</span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;"><strong>在串行处理操作中</strong>,Stream 在执行每一步中间操作时,并不会做实际的数据操作处理,而是将这些中间操作串联起来,最终由终结操作触发,生成一个数据处理链表,通过 Java8 中的 Spliterator 迭代器进行数据处理;此时,每执行一次迭代,就对所有的无状态的中间操作进行数据处理,而对有状态的中间操作,就需要迭代处理完所有的数据,再进行处理操作;最后就是进行终结操作的数据处理。</span></p> <p><br></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;"><strong>在并行处理操作中</strong>,Stream 对中间操作基本跟串行处理方式是一样的,但在终结操作中,Stream 将结合 ForkJoin 框架对集合进行切片处理,ForkJoin 框架将每个切片的处理结果 Join 合并起来。最后就是要注意 Stream 的使用场景。</span></p> <p><span style="font-family: "PingFang SC", "Lantinghei SC", "Microsoft Yahei", "Hiragino Sans GB", "Microsoft Sans Serif", "WenQuanYi Micro Hei", Helvetica, sans-serif;font-size: 16px;"><br></span></p> <section data-recommend-type="list-title" data-recommend-tid="8" data-mpa-template="t" style="width: 100%;display: flex;justify-content: center;align-items: center;" data-mid="" data-from="yb-recommend"> <section style="width: 100%;background: rgb(255, 255, 255);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(232, 232, 235);padding: 20px 14px;" data-mid=""> <section style="width: 100%;display: flex;justify-content: center;align-items: center;align-items: flex-end;" data-mid=""> <section style="display: flex;justify-content: center;align-items: center;max-width: 100%;background: #fff;margin-bottom: -10px;z-index: 10;" data-mid=""> <section style="width: 10px;height: 10px;border-radius: 50%;border-width: 1px;border-style: solid;border-color: rgb(51, 51, 51);" data-mid=""> <br> </section> <section style="margin: 0 8px;height: 20px;font-size: 14px;font-weight: 500;color: #333333;line-height: 20px;" data-mid=""> <p data-mid="">往期推荐</p> </section> <section style="width: 10px;height: 10px;border-radius: 50%;border-width: 1px;border-style: solid;border-color: rgb(51, 51, 51);" data-mid=""> <br> </section> </section> </section> <section style="width: 100%;height: 1px;background: rgb(51, 51, 51);margin-bottom: 16px;" data-mid=""> <br> </section> <section style="width: 100%;" data-mid=""> <section data-mpa-template="t" data-recommend-article-type="list-title" data-recomment-template-id="8" data-recommend-article-id="2247485051_1" data-recommend-article-time="1596587400" data-recommend-article-cover="http://mmbiz.qpic.cn/sz_mmbiz_jpg/d7YzaYDnrxEtSZibnQWhnlN5pPL3pc8AzyPczQMRiciaAqR4S9fJvncjjhjiajt5icrTicDGoRQPQlYiaaU7NAKa7icQJQ/0?wx_fmt=jpeg" data-recommend-article-title="如何避免服务停机带来的业务损失?" data-recommend-article-content-url="http://mp.weixin.qq.com/s?__biz=MzU3OTc1MDM1Mg==&mid=2247485051&idx=1&sn=fcfe3e566db01dbb1c3046cc0db99caa&chksm=fd6016c4ca179fd27d0ccfaf02b9e3558741fd33c920ec7129711b2b67e8c02c94018fb4becf#rd"> <a href="http://mp.weixin.qq.com/s?__biz=MzU3OTc1MDM1Mg==&mid=2247485051&idx=1&sn=fcfe3e566db01dbb1c3046cc0db99caa&chksm=fd6016c4ca179fd27d0ccfaf02b9e3558741fd33c920ec7129711b2b67e8c02c94018fb4becf&scene=21#wechat_redirect" data-linktype="2"> <section data-recommend-title="t" style="width: 100%;background: rgb(245, 245, 245);display: flex;justify-content: center;align-items: center;flex-wrap: nowrap;padding: 6px 16px;font-size: 13px;font-weight: 400;color: rgb(51, 51, 51);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="8" data-recommend-article-id="2247484976_1" data-recommend-article-time="1596533400" data-recommend-article-cover="http://mmbiz.qpic.cn/sz_mmbiz_jpg/d7YzaYDnrxEtSZibnQWhnlN5pPL3pc8AzC6K3dANNIJYRaF5cSb0M8ApZOpRHvpHOmutgIbNMDkib0CUd05UIkxQ/0?wx_fmt=jpeg" data-recommend-article-title="节点负载差距这么大,为什么收到的流量还一样?" data-recommend-article-content-url="http://mp.weixin.qq.com/s?__biz=MzU3OTc1MDM1Mg==&mid=2247484976&idx=1&sn=3c45a9c0d7319f8210a00c6cbe2cb16a&chksm=fd60168fca179f99763c48d9a56695a1bbfa8e48ba73cbe50acd7e22ad0564bd9244140caaf1#rd"> <a href="http://mp.weixin.qq.com/s?__biz=MzU3OTc1MDM1Mg==&mid=2247484976&idx=1&sn=3c45a9c0d7319f8210a00c6cbe2cb16a&chksm=fd60168fca179f99763c48d9a56695a1bbfa8e48ba73cbe50acd7e22ad0564bd9244140caaf1&scene=21#wechat_redirect" data-linktype="2"> <section data-recommend-title="t" style="width: 100%;display: flex;justify-content: center;align-items: center;flex-wrap: nowrap;padding: 6px 16px 6px;font-size: 13px;font-weight: 400;color: #333333;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="8" data-recommend-article-id="2247484928_1" data-recommend-article-time="1592352600" data-recommend-article-cover="http://mmbiz.qpic.cn/sz_mmbiz_jpg/d7YzaYDnrxHVZG5Oq840NfYwXubicGVibuxhqQLFAQcu7OphM213syHk6M6zAe4ZPdeJnvtR0OroWvx3JzOecz5g/0?wx_fmt=jpeg" data-recommend-article-title="用Redis构建缓存集群的最佳实践有哪些?" data-recommend-article-content-url="http://mp.weixin.qq.com/s?__biz=MzU3OTc1MDM1Mg==&mid=2247484928&idx=1&sn=0fc5683b5f0ccc0ff708b9f851bbb8cf&chksm=fd6016bfca179fa93af9305e19d16511ffd09c3b5cb4f14a25d278917287adbcbb3b03b9d401#rd"> <a href="http://mp.weixin.qq.com/s?__biz=MzU3OTc1MDM1Mg==&mid=2247484928&idx=1&sn=0fc5683b5f0ccc0ff708b9f851bbb8cf&chksm=fd6016bfca179fa93af9305e19d16511ffd09c3b5cb4f14a25d278917287adbcbb3b03b9d401&scene=21#wechat_redirect" data-linktype="2"> <section data-recommend-title="t" style="width: 100%;background: rgb(245, 245, 245);display: flex;justify-content: center;align-items: center;flex-wrap: nowrap;padding: 6px 16px;font-size: 13px;font-weight: 400;color: rgb(51, 51, 51);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="8" data-recommend-article-id="2247484912_1" data-recommend-article-time="1592266200" data-recommend-article-cover="http://mmbiz.qpic.cn/sz_mmbiz_jpg/d7YzaYDnrxFdQuJPZ7jlib3do2VnGj8uAIlgibpJicVlnWJJjheQgpS4fRC25tY1QiciaPicGNYzYeZNfHrLdG2fhjBA/0?wx_fmt=jpeg" data-recommend-article-title="Redis主从复制以及主从复制原理" data-recommend-article-content-url="http://mp.weixin.qq.com/s?__biz=MzU3OTc1MDM1Mg==&mid=2247484912&idx=1&sn=523f7e9739a3be55bfa4dc91362a8a8b&chksm=fd60154fca179c59df0f950db67a9bf5243e6158674251a3f5d03d9cf48ad0c2c852496b4926#rd"> <a href="http://mp.weixin.qq.com/s?__biz=MzU3OTc1MDM1Mg==&mid=2247484912&idx=1&sn=523f7e9739a3be55bfa4dc91362a8a8b&chksm=fd60154fca179c59df0f950db67a9bf5243e6158674251a3f5d03d9cf48ad0c2c852496b4926&scene=21#wechat_redirect" data-linktype="2"> <section data-recommend-title="t" style="width: 100%;display: flex;justify-content: center;align-items: center;flex-wrap: nowrap;padding: 6px 16px 6px;font-size: 13px;font-weight: 400;color: #333333;line-height: 18px;border-bottom:none !important;" data-mid=""> <p style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;max-width: 100%;" data-mid="">Redis主从复制以及主从复制原理</p> </section></a> </section> </section> </section> </section> <p><br></p>
作者:微信小助手
<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;"><span style="color: #888888;">点击上方蓝色“</span></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;"><span style="color: #888888;">”,选择“设为星标”</span></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: center;font-size: 15px;color: rgb(64, 64, 64);line-height: 1.74;letter-spacing: 0.008em;outline-style: none;overflow-wrap: break-word;"><img data-ratio="0.6260416666666667" src="/upload/42ba5c12cf3ba4052a831305e866bfd7.jpg" data-type="jpeg" data-w="960" style="display: inline;"></p> <p data-lake-id="b09a0d8047738e97364936a59eab5756" style="text-align: left;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(178, 178, 178);font-size: 13px;" data-mce-style="font-size: 10px">作者 | <span style="color: rgba(0, 0, 0, 0.5);font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 13px;letter-spacing: 0.544px;text-align: start;widows: 1;word-spacing: 1px;caret-color: rgb(255, 0, 0);background-color: rgb(255, 255, 255);">后青春期的Keats</span></span></p> <p data-lake-id="bfce4163fc935f17ecff696001dcbd90" style="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(178, 178, 178);font-size: 13px;" data-mce-style="font-size: 10px">来源 | <span style="color: rgba(0, 0, 0, 0.5);font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 13px;letter-spacing: 0.544px;text-align: start;widows: 1;word-spacing: 1px;caret-color: rgb(255, 0, 0);background-color: rgb(255, 255, 255);">www.cnblogs.com/keatsCoder/p/13217561.html</span></span></p> <h2 style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 1.2em;color: rgb(21, 153, 87);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);"><span style="font-size: inherit;color: inherit;line-height: inherit;">需求说明</span></h2> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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);">项目中有一个 Excel 导入的需求:缴费记录导入</p> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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);">由实施 / 用户 将别的系统的数据填入我们系统中的 Excel 模板,应用将文件内容读取、校对、转换之后产生欠费数据、票据、票据详情并存储到数据库中。</p> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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.0 版本,我预估导入时Excel 行数会是 10w+ 级别,而往数据库插入的数据量是大于 3n 的,也就是说 10w 行的 Excel,则至少向数据库插入 30w 行数据。</p> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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);">因此优化原来的导入代码是势在必行的。我逐步分析和优化了导入的代码,使之在百秒内完成(最终性能瓶颈在数据库的处理速度上,测试服务器 4g 内存不仅放了数据库,还放了很多微服务应用。处理能力不太行)。具体的过程如下,每一步都有列出影响性能的问题和解决的办法。</p> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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);">导入 Excel 的需求在系统中还是很常见的,我的优化办法可能不是最优的,欢迎读者在评论区留言交流提供更优的思路</p> <h2 style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 1.2em;color: rgb(21, 153, 87);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);"><span style="font-size: inherit;color: inherit;line-height: inherit;">一些细节</span></h2> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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);"><strong style="color: inherit;font-size: inherit;line-height: inherit;">数据导入:</strong>导入使用的模板由系统提供,格式是 xlsx (支持 65535+行数据) ,用户按照表头在对应列写入相应的数据</p> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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);"><strong style="color: inherit;font-size: inherit;line-height: inherit;">数据校验:</strong>数据校验有两种:</p> <ul style="padding-left: 25px;list-style: square;font-size: 14px;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="margin-bottom: 0.1em;font-size: inherit;color: inherit;line-height: inherit;"><p><span style="font-size: inherit;color: inherit;line-height: inherit;">字段长度、字段正则表达式校验等,内存内校验不存在外部数据交互。对性能影响较小</span></p></li> <li style="margin-bottom: 0.1em;font-size: inherit;color: inherit;line-height: inherit;"><p><span style="font-size: inherit;color: inherit;line-height: inherit;">数据重复性校验,如票据号是否和系统已存在的票据号重复(需要查询数据库,十分影响性能)</span></p></li> </ul> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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);"><strong style="color: inherit;font-size: inherit;line-height: inherit;">数据插入:</strong>测试环境数据库使用 MySQL 5.7,未分库分表,连接池使用 Druid</p> <h2 style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 1.2em;color: rgb(21, 153, 87);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);"><span style="font-size: inherit;color: inherit;line-height: inherit;">迭代记录</span></h2> <h3 style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 1.1em;color: rgb(21, 153, 87);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);"><span style="font-size: inherit;color: inherit;line-height: inherit;">第一版:POI + 逐行查询校对 + 逐行插入</span></h3> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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);">这个版本是最古老的版本,采用原生 POI,手动将 Excel 中的行映射成 ArrayList 对象,然后存储到 <code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: inherit;color: rgb(233, 105, 0);line-height: inherit;border-radius: 4px;background: rgb(248, 248, 248);">List<ArrayList></code> ,代码执行的步骤如下:</p> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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.手动读取 Excel 成 <code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: inherit;color: rgb(233, 105, 0);line-height: inherit;border-radius: 4px;background: rgb(248, 248, 248);">List<ArrayList></code></p> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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.循环遍历,在循环中进行以下步骤</p> <ul style="padding-left: 25px;list-style: square;font-size: 14px;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="margin-bottom: 0.1em;font-size: inherit;color: inherit;line-height: inherit;"><p><span style="font-size: inherit;color: inherit;line-height: inherit;">检验字段长度</span></p></li> <li style="margin-bottom: 0.1em;font-size: inherit;color: inherit;line-height: inherit;"><p><span style="font-size: inherit;color: inherit;line-height: inherit;">一些查询数据库的校验,比如校验当前行欠费对应的房屋是否在系统中存在,需要查询房屋表</span></p></li> <li style="margin-bottom: 0.1em;font-size: inherit;color: inherit;line-height: inherit;"><p><span style="font-size: inherit;color: inherit;line-height: inherit;">写入当前行数据</span></p></li> </ul> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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.返回执行结果,如果出错 / 校验不合格。则返回提示信息并回滚数据</p> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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> <ul style="padding-left: 25px;list-style: square;font-size: 14px;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="margin-bottom: 0.1em;font-size: inherit;color: inherit;line-height: inherit;"><p><span style="font-size: inherit;color: inherit;line-height: inherit;">查询数据库的校验对每一行数据都要查询一次数据库,应用访问数据库来回的网络IO次数被放大了 n 倍,时间也就放大了 n 倍</span></p></li> <li style="margin-bottom: 0.1em;font-size: inherit;color: inherit;line-height: inherit;"><p><span style="font-size: inherit;color: inherit;line-height: inherit;">写入数据也是逐行写入的,问题和上面的一样</span></p></li> <li style="margin-bottom: 0.1em;font-size: inherit;color: inherit;line-height: inherit;"><p><span style="font-size: inherit;color: inherit;line-height: inherit;">数据读取使用原生 POI,代码十分冗余,可维护性差。</span></p></li> </ul> <p><br></p> <p><span style="font-size: inherit;color: inherit;line-height: inherit;"><span style="background-color: rgb(255, 255, 255);font-size: 16px;letter-spacing: 0.544px;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;">推荐:</span><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzIyNDU2ODA4OQ==&mid=2247484532&idx=1&sn=1c243934507d79db4f76de8ed0e5727f&chksm=e80db202df7a3b14fe7077b0fe5ec4de4088ce96a2cde16cbac21214956bd6f2e8f51193ee2b&scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="color: rgb(0, 0, 0);font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;font-size: 15px;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;letter-spacing: 0.544px;">100期面试题汇总</a><span style="color: rgb(62, 62, 62);font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;font-size: 15px;text-align: start;background-color: rgb(255, 255, 255);"></span></span></p> <h3 style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 1.1em;color: rgb(21, 153, 87);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);"><span style="font-size: inherit;color: inherit;line-height: inherit;">第二版:EasyPOI + 缓存数据库查询操作 + 批量插入</span></h3> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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> <h4 style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;color: rgb(21, 153, 87);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);"><span style="font-size: inherit;color: inherit;line-height: inherit;">缓存数据,以空间换时间</span></h4> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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);">逐行查询数据库校验的时间成本主要在来回的网络IO中,优化方法也很简单。将参加校验的数据全部缓存到 HashMap 中。直接到 HashMap 去命中。</p> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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);">例如:校验行中的房屋是否存在,原本是要用 区域 + 楼宇 + 单元 + 房号 去查询房屋表匹配房屋ID,查到则校验通过,生成的欠单中存储房屋ID,校验不通过则返回错误信息给用户。而房屋信息在导入欠费的时候是不会更新的。</p> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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);">并且一个小区的房屋信息也不会很多(5000以内)因此我采用一条SQL,将该小区下所有的房屋以 区域/楼宇/单元/房号 作为 key,以 房屋ID 作为 value,存储到 HashMap 中,后续校验只需要在 HashMap 中命中</p> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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);"><strong style="color: inherit;font-size: inherit;line-height: inherit;">自定义 SessionMapper</strong></p> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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);">Mybatis 原生是不支持将查询到的结果直接写人一个 HashMap 中的,需要自定义 SessionMapper</p> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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);">SessionMapper 中指定使用 MapResultHandler 处理 SQL 查询的结果集</p> <pre style="font-size: 15px;color: rgb(62, 62, 62);line-height: inherit;text-align: start;background-color: rgb(255, 255, 255);"><code style="margin-right: 2px;margin-left: 2px;padding: 0.5em;font-size: 14px;color: white;line-height: 15px;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="font-size: inherit;color: rgb(252, 155, 155);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">@Repository</span><br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="font-size: inherit;color: rgb(252, 194, 140);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">public</span> <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="font-size: inherit;color: rgb(252, 194, 140);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">class</span> <span style="font-size: inherit;color: rgb(255, 255, 170);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">SessionMapper</span> <span style="font-size: inherit;color: rgb(255, 255, 170);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">extends</span> <span style="font-size: inherit;color: rgb(255, 255, 170);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">SqlSessionDaoSupport</span> </span>{<br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="font-size: inherit;color: rgb(252, 155, 155);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">@Resource</span><br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="font-size: inherit;color: rgb(252, 194, 140);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">public</span> void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {<br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="font-size: inherit;color: rgb(252, 194, 140);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">super</span>.setSqlSessionFactory(sqlSessionFactory);<br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> }<br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="font-size: inherit;color: rgb(136, 136, 136);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">// 区域楼宇单元房号 - 房屋ID</span><br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="font-size: inherit;color: rgb(252, 155, 155);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">@SuppressWarnings(<span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">"unchecked"</span>)</span><br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="font-size: inherit;color: rgb(252, 194, 140);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">public</span> Map<String, <span style="font-size: inherit;color: rgb(255, 255, 170);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">Long</span>> getHouseMapByAreaId(<span style="font-size: inherit;color: rgb(255, 255, 170);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">Long</span> areaId) {<br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> MapResultHandler handler = new MapResultHandler();<br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="font-size: inherit;color: rgb(252, 194, 140);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">this</span>.getSqlSession().select(BaseUnitMapper.<span style="font-size: inherit;color: rgb(252, 194, 140);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">class</span>.getName()+<span style="font-size: inherit;color: rgb(162, 252, 162);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">".getHouseMapByAreaId"</span>, areaId, handler);<br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> Map<String, <span style="font-size: inherit;color: rgb(255, 255, 170);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">Long</span>> map = handler.getMappedResults();<br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="font-size: inherit;color: rgb(252, 194, 140);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">return</span> map;<br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> }<br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">} <br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"></code></pre> <p style="margin-top: 1.3em;margin-bottom: 1.3em;font-size: 15px;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);">MapResultHandler 处理程序,将结果集放入 HashMap</p> <pre style="font-size: 15px;color: rgb(62, 62, 62);line-height: inherit;text-align: start;background-color: rgb(255, 255, 255);"><code style="margin-right: 2px;margin-left: 2px;padding: 0.5em;font-size: 14px;color: white;line-height: 15px;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="font-size: inherit;color: rgb(252, 194, 140);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">public</span> <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="font-size: inherit;color: rgb(252, 194, 140);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">class</span> <span style="font-size: inherit;color: rgb(255, 255, 170);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">MapResultHandler</span> <span style="font-size: inherit;color: rgb(252, 194, 140);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">implements</span> <span style="font-size: inherit;color: rgb(255, 255, 170);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">ResultHandler</span> </span>{<br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="font-size: inherit;color: rgb(252, 194, 140);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">private</span> <span style="font-size: inherit;color: rgb(252, 194, 140);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">final</span> Map mappedResults = <span style="font-size: inherit;color: rgb(252, 194, 140);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">new</span> HashMap();<br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="font-size: inherit;color: rgb(252, 155, 155);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">@Override</span><br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="font-size: inherit;color: rgb(252, 194, 140);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">public</span> <span style="font-size: inherit;color: rgb(252, 194, 140);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">void</span> <span style="font-size: inherit;color: rgb(255, 255, 170);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">handleResult</span><span style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">(ResultContext context)</span> </span>{<br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> <span style="font-size: inherit;color: rgb(252, 155, 155);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">@SuppressWarnings</span>(<span style="font-size: inherit;color: rgb(162, 252, 162);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">"rawtypes"</span>)<br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> Map map = (Map)context.getResultObject();<br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;"> mappedResults.put(map.get(<span style="font-size: inherit;color: rgb(162, 252, 162);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">"key"</span>), map.get(<span style="font-size: inherit;color: rgb(162, 252, 162);line-height: inherit;overflow-wrap: inherit !important;word-break: inherit !important;">"value"</span>));<br style="font-size: inherit;color: inherit;line-height: inherit;overflow-wrap:
作者:微信小助手
<p style="margin-bottom: 10px;max-width: 100%;min-height: 1em;color: rgb(62, 62, 62);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.544px;white-space: normal;background-color: rgb(255, 255, 255);line-height: normal;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;letter-spacing: 0.544px;font-size: 12px;color: rgb(136, 136, 136);box-sizing: border-box !important;overflow-wrap: break-word !important;"> </span><span style="max-width: 100%;font-size: 14px;letter-spacing: 0.544px;word-spacing: 2px;color: rgb(136, 136, 136);box-sizing: border-box !important;overflow-wrap: break-word !important;">点击蓝色“</span><span style="max-width: 100%;font-size: 14px;letter-spacing: 0.544px;word-spacing: 2px;color: rgb(0, 128, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;">架构文摘</span><span style="max-width: 100%;font-size: 14px;letter-spacing: 0.544px;word-spacing: 2px;color: rgb(136, 136, 136);box-sizing: border-box !important;overflow-wrap: break-word !important;">”关注我哟</span></p> <p style="margin-bottom: 10px;max-width: 100%;min-height: 1em;color: rgb(62, 62, 62);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.544px;white-space: normal;background-color: rgb(255, 255, 255);text-size-adjust: auto;word-spacing: 2px;text-align: center;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;color: rgb(62, 62, 62);letter-spacing: 0.544px;white-space: normal;font-size: 14px;font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;background-color: rgb(255, 255, 255);text-align: center;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" data-type="jpeg" data-w="640" width="100%" src="/upload/8c292e55ba5a23cb6ebc11f2a2c4fece.jpg" 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;"></p> <p style="max-width: 100%;min-height: 1em;letter-spacing: 0.544px;text-align: left;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;letter-spacing: 0.544px;text-align: left;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 12px;box-sizing: border-box !important;overflow-wrap: break-word !important;">转自:一入码坑深似海</span></p> <p style="max-width: 100%;min-height: 1em;letter-spacing: 0.544px;text-align: left;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 12px;box-sizing: border-box !important;overflow-wrap: break-word !important;">链接:www.jianshu.com/p/cb9f4dcb3b92</span></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);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> <h2 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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(123, 12, 0);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;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">1. 命令行</span></strong></span></h2> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">不知道大家在日常操作redis时用什么可视化工具呢?</span></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">以前总觉得没有什么太好的可视化工具,于是问了一个业内朋友。对方回:你还用可视化工具?直接命令行呀,redis提供了这么多命令,操作起来行云流水。用可视化工具觉得很low。</span></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">命令行的鄙视用工具的,用高端工具的鄙视低端工具的,鄙视链一直存在。虽然用命令行自己也可以,但是总感觉效率上不如用工具,在视觉上不那么直观。尤其是看json的时候,在命令行就很不友好。</span></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">大佬朋友说:谁说命令行就不能格式化json了?可以利用iredis,用</span><code style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">|</span></code><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">将redis通过pipe用shell的其他工具,比如</span><code style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">jq/fx/rg/sort/uniq/cut/sed/awk</span></code><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">等处理。还能自动补全,高亮显示,功能很多</span></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><img data-ratio="0.69" data-type="jpeg" data-w="800" src="/upload/a0989b7dd34e7db15384acd0805db70f.jpg" style="cursor: zoom-in;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 677px !important;"></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">好吧 ,确实牛逼。附上这个工具的官网地址,喜欢用命令行的朋友可以去试一试,绝对能让喜欢命令行的你爽的飞起来。</span></p> <blockquote style="color: rgba(0, 0, 0, 0.498);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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"> <p style="max-width: 100%;min-height: 1em;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;">https://iredis.io/</span></p> </blockquote> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">但是我相信大多数开发者还是习惯用可视化工具。我自己也用过不少redis的可视化工具。今天就细数下市面上流行的各个可视化的工具的优劣势。帮助你找到最好的redis可视化工具。提升debug效率。</span></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">如果你想直接看最终总结,可以直接拉到文章的末尾。</span></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);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> <h2 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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(123, 12, 0);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;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">2. 可视化工具分类</span></strong></span></h2> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">按照redis可视化工具的部署来分,可以分成3大类</span></p> <ul class="list-paddingleft-2" 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;white-space: normal;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;"> <li style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="max-width: 100%;min-height: 1em;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;">桌面客户端版</span></p></li> <li style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="max-width: 100%;min-height: 1em;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;">web版</span></p></li> <li style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="max-width: 100%;min-height: 1em;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;">IDE工具的plugin</span></p></li> </ul> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">桌面版这次评测的软件如下:</span></p> <ul class="list-paddingleft-2" 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;white-space: normal;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;"> <li style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="max-width: 100%;min-height: 1em;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;">redis desktop manager</span></p></li> <li style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="max-width: 100%;min-height: 1em;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;">medis</span></p></li> <li style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="max-width: 100%;min-height: 1em;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;">AnotherRedisDesktopManager</span></p></li> <li style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="max-width: 100%;min-height: 1em;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;">fastoredis</span></p></li> <li style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="max-width: 100%;min-height: 1em;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;">redis-plus</span></p></li> <li style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="max-width: 100%;min-height: 1em;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;">red</span></p></li> </ul> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">Web版本评测的软件如下:</span></p> <ul class="list-paddingleft-2" 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;white-space: normal;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;"> <li style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="max-width: 100%;min-height: 1em;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;">redis-insight</span></p></li> </ul> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">IDE插件版本,这里只评测IntelliJ IDEA的插件,eclipse的就不作介绍了</span></p> <ul class="list-paddingleft-2" 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;white-space: normal;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;"> <li style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p style="max-width: 100%;min-height: 1em;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;">Iedis2</span></p><p style="max-width: 100%;min-height: 1em;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></li> </ul> <h2 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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(123, 12, 0);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;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">3. Redis Desktop Manager</span></strong></span></h2> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">这个工具应该是现在使用率最广的可视化工具了。存在时间很久。经过了数次迭代。跨平台支持。以前是免费的,现在为收费工具。试用可以有半个月的时间。<span style="max-width: 100%;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;">链接为:</span></span></p> <blockquote style="color: rgba(0, 0, 0, 0.498);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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"> <p style="max-width: 100%;min-height: 1em;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;">https://redisdesktop.com/</span></p> </blockquote> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><img data-ratio="0.74625" data-type="jpeg" data-w="800" src="/upload/8a145ec4692b06240133202b3676c226.jpg" style="cursor: zoom-in;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 677px !important;"></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;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></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">之前用觉得功能还行,就是界面UI丑了点。最近下了最新版,感觉经过了那么长时间迭代,界面看着也还凑合。该有的功能都有。界面看着比较简洁,功能很全。</span></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">key的显示可以支持按冒号分割的键名空间,除了基本的五大数据类型之外,还支持redis 5.0新出的Stream数据类型。在value的显示方面。支持多达9种的数据显示方式。</span></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><img data-ratio="1.3383458646616542" data-type="jpeg" data-w="266" src="/upload/2621aebafbdd7fe03e31aa927dcc433f.jpg" style="cursor: zoom-in;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 266px !important;"></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">命令行模式也同以前有了很大的进步,支持了命令自动提示。</span></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><img data-ratio="0.29125" data-type="jpeg" data-w="800" src="/upload/48e77203966d361b16ca78cf9b502927.jpg" style="cursor: zoom-in;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 677px !important;"></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">从功能看上去中规中矩,使用起来便捷。最大的缺点就是不免费。个人使用的话,大概一年要200多RMB的价格。</span></p> <h2 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;white-space: normal;background-color: rgb(255, 255, 255);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;"></h2> <h2 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;white-space: normal;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 !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(123, 12, 0);font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">4.medis</span></strong></h2> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">现阶段我使用率最高的redis可视化工具。界面符合个人审美。布局简洁。跨平台支持,关键是免费。<span style="max-width: 100%;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;">链接为:</span></span></p> <blockquote style="color: rgba(0, 0, 0, 0.498);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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"> <p style="max-width: 100%;min-height: 1em;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;">http://getmedis.com/</span></p> </blockquote> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><img data-ratio="0.6575" data-type="jpeg" data-w="800" src="/upload/17887b12bf6f080232bd520fbe357a6e.jpg" style="cursor: zoom-in;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 677px !important;"></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;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></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">颜值挺高,功能符合日常使用要求。对key有颜色鲜明的图标标识。在key的搜索上挺方便的,可以模糊搜索出匹配的key,渐进式的scan,无明显卡顿。在搜索的体验上还是比较出色的。</span></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">缺点是不支持key的命名空间展示,不支持redis 5.0的stream数据类型,命令行比较单一,不支持自动匹配和提示。支持的value的展现方式也只有3种</span></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><img data-ratio="0.2898550724637681" data-type="jpeg" data-w="414" src="/upload/fe8b31d5a92351277ca33279e85c0110.jpg" style="cursor: zoom-in;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 414px !important;"></p> <h2 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;white-space: normal;background-color: rgb(255, 255, 255);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;"></h2> <h2 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;white-space: normal;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 !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(123, 12, 0);font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">5.AnotherRedisDesktopManager</span></strong></h2> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);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;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">一款比较稳定简洁的redis UI工具。<span style="max-width: 100%;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;">链接为:</span></span></p> <blockquote style="color: rgba(0, 0, 0, 0.498);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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"> <p style="max-width: 100%;min-height: 1em;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;">https://github.com/qishibo/AnotherRedisDesktopManager</span></p> </blockquote> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><img data-ratio="0.65125" data-type="jpeg" data-w="800" src="/upload/606060e2ea0565b3c5acf752760d5637.jpg" style="cursor: zoom-in;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 677px !important;"></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);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;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;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></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">很中规中矩的一款免费的redis可视化工具,基本的功能都有。有监控统计,支持暗黑主题,还支持集群的添加。</span></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">缺点是没什么亮点,UI很简单,不支持stream数据类型。命令行模式也比较单一。value展示支持的类型也只有3种。</span></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><img data-ratio="1.3235294117647058" data-type="jpeg" data-w="272" src="/upload/50e670687d6f864ae9f8e9ac1fd8efe5.jpg" style="cursor: zoom-in;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 272px !important;"></p> <h2 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;white-space: normal;background-color: rgb(255, 255, 255);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;"></h2> <h2 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;white-space: normal;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 !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(123, 12, 0);font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">6.FastoRedis</span></strong></h2> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">FastoRedis之前没听到过。然后去下了体验了下。</span></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">使用这款工具首先得去官网注册账号。这款软件是收费软件,虽然跨平台,但是试用只有一天的时间。<span style="max-width: 100%;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;">链接为:</span></span></p> <blockquote style="color: rgba(0, 0, 0, 0.498);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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"> <p style="max-width: 100%;min-height: 1em;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;">https://fastoredis.com/</span></p> </blockquote> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><img data-ratio="0.77" data-type="jpeg" data-w="800" src="/upload/25fe54c3a545dd373b2ed5fbbe2b8f6.jpg" style="cursor: zoom-in;box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 677px !important;"></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;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></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">毕竟是收费软件,虽然界面一股浓浓的windows风格,乍看上去有点像redis desktop manager,但是就功能而言。确实不错,支持了集群模式和哨兵模式,key的命名空间展示,redis 5.0的stream数据类型也支持。</span></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">命令行模式支持自动提示补全</span></p> <p style="max-width: 100%;min-height: 1em;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;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><img data-ratio="0.65" d
作者:微信小助手
<p style="text-align: center;"><span style="font-size: 14px;letter-spacing: 0.5440000295639038px;text-align: center;max-width: 100%;color: rgb(255, 41, 65);line-height: 22.4px;">(给</span><span style="font-size: 14px;letter-spacing: 0.5440000295639038px;text-align: center;max-width: 100%;line-height: 22.4px;color: rgb(0, 128, 255);">ImportNew</span><span style="font-size: 14px;letter-spacing: 0.5440000295639038px;text-align: center;max-width: 100%;color: rgb(255, 41, 65);line-height: 22.4px;">加星标,提高Java技能)</span></p> <blockquote class="js_blockquote_wrap" data-type="2" data-url="" data-author-name="" data-content-utf8-length="8" data-source-title=""> <section class="js_blockquote_digest"> <p>转自:三太子敖丙</p> </section> </blockquote> <p><span style="color: rgb(123, 12, 0);font-size: 15px;background-color: rgb(255, 255, 255);font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-weight: bold;letter-spacing: 2px;word-spacing: 2px;">前言</span></p> <h2 style="margin-top: 1.6em;margin-bottom: 1.6em;font-weight: bold;font-size: 1.4em;max-width: 100%;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><strong style="font-size: inherit;max-width: 100%;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Redis</strong><span style="font-size: 15px;color: inherit;">在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在</span><strong style="font-size: inherit;max-width: 100%;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Redis</strong><span style="font-size: 15px;color: inherit;">的使用和原理方面对小伙伴们进行360°的刁难。作为一个在互联网公司面一次拿一次offer的面霸(</span><strong style="font-size: inherit;max-width: 100%;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">请允许我使用一下夸张的修辞手法</strong><span style="font-size: 15px;color: inherit;">),打败了无数竞争对手,每次都只能看到无数落寞的身影失望的离开,略感愧疚,在一个寂寞难耐的夜晚,我痛定思痛,决定开始写</span><strong style="font-size: inherit;max-width: 100%;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">吊打面试官</strong><span style="font-size: 15px;color: inherit;">系列,希望能帮助各位读者以后面试势如破竹,对面试官进行360°的反击,吊打问你的面试官,让一同面试的同僚瞠目结舌,疯狂收割大厂offer。</span></span></h2> <h2 style="margin-top: 1.6em;margin-bottom: 1.6em;font-weight: bold;font-size: 1.4em;max-width: 100%;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: inherit;font-size: 15px;color: rgb(123, 12, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">正文</span></h2> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">上一期吊打系列我们提到了Redis的基础知识,还没看的小伙伴可以回顾一下</span></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><a href="http://mp.weixin.qq.com/s?__biz=MzAwNDA2OTM1Ng==&mid=2453140867&idx=2&sn=5c573be40ff3e897bed2ede542ef8c34&chksm=8cf2d700bb855e166f6c8db7d89185b26139ace92ef70484084ce2abd9a6c9e66eb0f84b9695&scene=21#wechat_redirect" target="_blank" data-itemshowtype="0" data-linktype="2" hasload="1" style="color: var(--weui-LINK);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">《吊打面试官》系列-Redis基础</span></a></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">那提到<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Redis</strong>我相信各位在面试,或者实际开发过程中对缓存<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">雪崩</strong>,<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">穿透</strong>,<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">击穿</strong>也不陌生吧,就算没遇到过但是你肯定听过,那三者到底有什么区别,我们又应该怎么去防止这样的情况发生呢,我们有请下一位受害者。</span></p> <h2 style="margin-top: 1.6em;margin-bottom: 1.6em;font-weight: bold;font-size: 1.4em;max-width: 100%;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: inherit;font-size: 15px;color: rgb(123, 12, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">面试开始</span></h2> <blockquote style="padding: 15px 15px 15px 1rem;border-left-width: 5px;border-left-color: rgb(239, 112, 96);color: rgb(0, 0, 0);font-size: 0.9em;max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 2px;white-space: normal;word-spacing: 2px;line-height: inherit;background: rgb(239, 235, 233);overflow: auto;word-break: normal;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <p style="max-width: 100%;min-height: 1em;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">一个大腹便便,穿着格子衬衣的中年男子,拿着一个满是划痕的mac向你走来,看着快秃顶的头发,心想着肯定是尼玛顶级架构师吧!但是我们腹有诗书气自华,虚都不虚。</span></p> </blockquote> <figure style="max-width: 100%;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <img data-ratio="0.5625" data-type="jpeg" data-w="800" title="" src="/upload/558457aaa48f960dd9338b1db4a6acf.jpg" style="margin-right: auto;margin-left: auto;font-size: inherit;color: inherit;line-height: inherit;display: block;box-sizing: border-box !important;overflow-wrap: break-word !important;width: 677px !important;visibility: visible !important;"> </figure> <h3 style="margin-top: 1.6em;margin-bottom: 1.6em;font-weight: bold;font-size: 1.3em;max-width: 100%;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;border-bottom: 2px solid rgb(128, 128, 128);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><span style="margin-right: 3px;padding: 3px 10px 1px;max-width: 100%;line-height: inherit;display: inline-block;font-weight: normal;background: rgb(128, 128, 128);color: rgb(255, 255, 255);border-top-right-radius: 3px;border-top-left-radius: 3px;box-sizing: border-box !important;overflow-wrap: break-word !important;">小伙子我看你的简历上写到了Redis,那么我们直接开门见山,直接怼常见的几个大问题,Redis雪崩了解么?</span></span></h3> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">帅气迷人的面试官您好,我了解的,目前电商首页以及热点数据都会去做缓存 ,一般缓存都是定时任务去刷新,或者是查不到之后去更新的,定时任务刷新就有一个问题。</span></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">举个简单的例子</strong>:如果所有首页的Key失效时间都是12小时,中午12点刷新的,我零点有个秒杀活动大量用户涌入,假设当时每秒 6000 个请求,本来缓存在可以扛住每秒 5000 个请求,但是缓存当时所有的Key都失效了。此时 1 秒 6000 个请求全部落数据库,数据库必然扛不住,它会报一下警,真实情况可能DBA都没反应过来就直接挂了。此时,如果没用什么特别的方案来处理这个故障,DBA 很着急,重启数据库,但是数据库立马又被新的流量给打死了。这就是我理解的缓存雪崩。</span></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">我刻意看了下我做过的项目感觉再吊的都不允许这么大的QPS直接打DB去,不过没慢SQL加上分库,大表分表可能还还算能顶,但是跟用了Redis的差距还是很大</strong></span></p> <figure style="max-width: 100%;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <img data-ratio="0.8710801393728222" data-type="png" title="" data-w="574" src="/upload/9ab9a3b1cc4f9962e5caf175a256a8d6.png" style="margin-right: auto;margin-left: auto;font-size: inherit;color: inherit;line-height: inherit;display: block;box-sizing: border-box !important;overflow-wrap: break-word !important;width: 574px !important;visibility: visible !important;"> </figure> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">同一时间大面积失效,那一瞬间Redis跟没有一样,那这个数量级别的请求直接打到数据库几乎是灾难性的,你想想如果打挂的是一个用户服务的库,那其他依赖他的库所有的接口几乎都会报错,如果没做熔断等策略基本上就是瞬间挂一片的节奏,你怎么重启用户都会把你打挂,等你能重启的时候,用户早就睡觉去了,并且对你的产品失去了信心,什么垃圾产品。</strong></span></p> <h3 style="margin-top: 1.6em;margin-bottom: 1.6em;font-weight: bold;font-size: 1.3em;max-width: 100%;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;border-bottom: 2px solid rgb(128, 128, 128);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><span style="margin-right: 3px;padding: 3px 10px 1px;max-width: 100%;line-height: inherit;display: inline-block;font-weight: normal;background: rgb(128, 128, 128);color: rgb(255, 255, 255);border-top-right-radius: 3px;border-top-left-radius: 3px;box-sizing: border-box !important;overflow-wrap: break-word !important;">面试官摸了摸自己的头发,嗯还不错,那这种情况咋整?你都是怎么去应对的?</span></span></h3> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">处理缓存雪崩简单,在批量往<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Redis</strong>存数据的时候,把每个Key的失效时间都加个随机值就好了,这样可以保证数据不会在同一时间大面积失效,我相信,Redis这点流量还是顶得住的。</span></p> <pre style="max-width: 100%;color: inherit;font-size: inherit;letter-spacing: 2px;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><code style="margin-right: 2px;margin-left: 2px;padding: 0.5em;max-width: 100%;line-height: 18px;font-size: 14px;word-spacing: 0px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);background: rgb(40, 43, 46);box-sizing: border-box !important;overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: 15px;">setRedis(Key,value,time + Math.random() * <span style="max-width: 100%;line-height: inherit;color: rgb(174, 135, 250);box-sizing: border-box !important;overflow-wrap: inherit !important;word-break: inherit !important;">10000</span>);<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></code></pre> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">如果<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Redis</strong>是集群部署,将热点数据均匀分布在不同的<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Redis</strong>库中也能避免全部失效的问题,不过本渣我在生产环境中操作集群的时候,单个服务都是对应的单个<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Redis</strong>分片,是为了方便数据的管理,但是也同样有了可能会失效这样的弊端,失效时间随机是个好策略。</span></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">或者设置热点数据永远不过期,有更新操作就更新缓存就好了(比如运维更新了首页商品,那你刷下缓存就完事了,不要设置过期时间),电商首页的数据也可以用这个操作,保险。</span></p> <h3 style="margin-top: 1.6em;margin-bottom: 1.6em;font-weight: bold;font-size: 1.3em;max-width: 100%;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;border-bottom: 2px solid rgb(128, 128, 128);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><span style="margin-right: 3px;padding: 3px 10px 1px;max-width: 100%;line-height: inherit;display: inline-block;font-weight: normal;background: rgb(128, 128, 128);color: rgb(255, 255, 255);border-top-right-radius: 3px;border-top-left-radius: 3px;box-sizing: border-box !important;overflow-wrap: break-word !important;">那你了解缓存穿透和击穿么,可以说说他们跟雪崩的区别么?</span></span></h3> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">嗯,了解,我先说一下缓存穿透吧,缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,我们数据库的 id 都是1开始自增上去的,如发起为id值为 -1 的数据或 id 为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大,严重会击垮数据库。</span></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">小点的单机系统,基本上用postman就能搞死,比如我自己买的阿里云服务</strong></span></p> <figure style="max-width: 100%;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <img data-ratio="1.0480349344978166" data-type="png" data-w="458" title="" src="/upload/6ebe4c3b3d7d1ce0d1ff6f5ee85ee23a.png" style="margin-right: auto;margin-left: auto;font-size: inherit;color: inherit;line-height: inherit;display: block;box-sizing: border-box !important;overflow-wrap: break-word !important;width: 458px !important;visibility: visible !important;"> </figure> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">像这种你如果不对参数做校验,数据库id都是大于0的,我一直用小于0的参数去请求你,每次都能绕开Redis直接打到数据库,数据库也查不到,每次都这样,并发高点就容易崩掉了。</strong></span></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">至于<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">缓存击穿</strong>嘛,这个跟<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">缓存雪崩</strong>有点像,但是又有一点不一样,缓存雪崩是因为大面积的缓存失效,打崩了DB,而缓存击穿不同的是<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">缓存击穿</strong>是指一个Key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个Key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个完好无损的桶上凿开了一个洞。</span></p> <figure style="max-width: 100%;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <img data-ratio="0.666" data-type="jpeg" data-w="1000" title="" src="/upload/2b63dafd90a5e158f489ef15007e9240.jpg" style="margin-right: auto;margin-left: auto;font-size: inherit;color: inherit;line-height: inherit;display: block;box-sizing: border-box !important;overflow-wrap: break-word !important;width: 677px !important;visibility: visible !important;"> </figure> <h3 style="margin-top: 1.6em;margin-bottom: 1.6em;font-weight: bold;font-size: 1.3em;max-width: 100%;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;border-bottom: 2px solid rgb(128, 128, 128);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><span style="margin-right: 3px;padding: 3px 10px 1px;max-width: 100%;line-height: inherit;display: inline-block;font-weight: normal;background: rgb(128, 128, 128);color: rgb(255, 255, 255);border-top-right-radius: 3px;border-top-left-radius: 3px;box-sizing: border-box !important;overflow-wrap: break-word !important;">面试官露出欣慰的眼光,那他们分别怎么解决</span></span></h3> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">缓存穿透</strong>我会在接口层增加校验,比如用户鉴权校验,参数做校验,不合法的参数直接代码Return,比如:id 做基础校验,id <=0的直接拦截等。</span></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">这里我想提的一点就是,我们在开发程序的时候都要有一颗“不信任”的心,就是不要相信任何调用方,比如你提供了API接口出去,你有这几个参数,那我觉得作为被调用方,任何可能的参数情况都应该被考虑到,做校验,因为你不相信调用你的人,你不知道他会传什么参数给你。</strong></span></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">举个简单的例子,你这个接口是分页查询的,但是你没对分页参数的大小做限制,调用的人万一一口气查 Integer.MAX_VALUE 一次请求就要你几秒,多几个并发你不就挂了么?是公司同事调用还好大不了发现了改掉,但是如果是黑客或者竞争对手呢?在你双十一当天就调你这个接口会发生什么,就不用我说了吧。这是之前的Leader跟我说的,我觉得大家也都应该了解下。</strong></span></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">从缓存取不到的数据,在数据库中也没有取到,这时也可以将对应Key的Value对写为null、位置错误、稍后重试这样的值具体取啥问产品,或者看具体的场景,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。</span></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">这样可以防止攻击用户反复用同一个id暴力攻击,但是我们要知道正常用户是不会在单秒内发起这么多次请求的,那网关层<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Nginx</strong>本渣我也记得有配置项,可以让运维大大对单个IP每秒访问次数超出阈值的IP都拉黑。</span></p> <h3 style="margin-top: 1.6em;margin-bottom: 1.6em;font-weight: bold;font-size: 1.3em;max-width: 100%;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;border-bottom: 2px solid rgb(128, 128, 128);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><span style="margin-right: 3px;padding: 3px 10px 1px;max-width: 100%;line-height: inherit;display: inline-block;font-weight: normal;background: rgb(128, 128, 128);color: rgb(255, 255, 255);border-top-right-radius: 3px;border-top-left-radius: 3px;box-sizing: border-box !important;overflow-wrap: break-word !important;">那你还有别的办法么?</span></span></h3> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">还有我记得<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Redis</strong>还有一个高级用法<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">布隆过滤器(Bloom Filter)</strong>这个也能很好的防止缓存穿透的发生,他的原理也很简单就是利用高效的数据结构和算法快速判断出你这个Key是否在数据库中存在,不存在你return就好了,存在你就去查了DB刷新KV再return。</span></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">那又有小伙伴说了如果黑客有很多个IP同时发起攻击呢?这点我一直也不是很想得通,但是一般级别的黑客没这么多肉鸡,再者正常级别的<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Redis</strong>集群都能抗住这种级别的访问的,小公司我想他们不会感兴趣的。把系统的高可用做好了,集群还是很能顶的。</span></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">缓存击穿</strong>的话,设置热点数据永远不过期。或者加上互斥锁就能搞定了</span></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">作为暖男,代码我肯定帮你们准备好了</strong></span></p> <section style="max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: 1.8;background-image: linear-gradient(90deg, rgba(50, 0, 0, 0.047) 3%, rgba(0, 0, 0, 0) 3%), linear-gradient(360deg, rgba(50, 0, 0, 0.047) 3%, rgba(0, 0, 0, 0) 3%);background-size: 20px 20px;background-position: center center;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <figure style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <img data-ratio="0.9854014598540146" data-type="jpeg" data-w="1096" title="" src="/upload/86b2182404272ad44407c5a70747fcc5.jpg" style="margin-right: auto;margin-left: auto;font-size: inherit;color: inherit;line-height: inherit;display: block;box-sizing: border-box !important;overflow-wrap: break-word !important;width: 677px !important;visibility: visible !important;"> </figure> </section> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;max-width: 100%;color: rgb(123, 12, 0);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></p> <h3 style="margin-top: 1.6em;margin-bottom: 1.6em;font-weight: bold;font-size: 1.3em;max-width: 100%;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;border-bottom: 2px solid rgb(128, 128, 128);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><span style="margin-right: 3px;padding: 3px 10px 1px;max-width: 100%;line-height: inherit;display: inline-block;font-weight: normal;background: rgb(128, 128, 128);color: rgb(255, 255, 255);border-top-right-radius: 3px;border-top-left-radius: 3px;box-sizing: border-box !important;overflow-wrap: break-word !important;">嗯嗯还不错,三个点都回答得很好,今天也不早了,面试就先到这里,明天你再过来二面我继续问一下你关于Redis集群高可用,主从同步,哨兵等知识点的问题。</span></span></h3> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">晕居然还有下一轮面试!(强行下一期的伏笔哈哈)但是为了offer还是得舔,嗯嗯,好的帅气面试官。</span></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">能回答得这么全面这么细节还是忍不住点赞</span></p> <h2 style="margin-top: 1.6em;margin-bottom: 1.6em;font-weight: bold;font-size: 1.4em;max-width: 100%;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;line-height: inherit;font-size: 15px;color: rgb(123, 12, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">总结</span></h2> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">我们玩归玩,闹归闹,别拿面试开玩笑。</span></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">本文简单的介绍了,<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Redis</strong>的<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">雪崩</strong>,<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">击穿</strong>,<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">穿透</strong>,三者其实都差不多,但是又有一些区别,在面试中其实这是问到缓存必问的,大家不要把三者搞混了,因为缓存雪崩、穿透和击穿,是缓存最大的问题,要么不出现,一旦出现就是致命性的问题,所以面试官一定会问你。</span></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">大家一定要理解是<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">怎么发生的</strong>,以及是怎么去<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">避免</strong>的,发生之后又怎么去<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">抢救</strong>,你可以不是知道很深入,但是你不能一点都不去想,面试有时候不一定是对知识面的拷问,或许是对你的态度的拷问,如果你思路清晰,然后<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">知其然还知其所以然</strong>那就很赞,还知道怎么预防那来上班吧。</span></p> <h3 style="margin-top: 1.6em;margin-bottom: 1.6em;font-weight: bold;font-size: 1.3em;max-width: 100%;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;border-bottom: 2px solid rgb(128, 128, 128);box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><span style="margin-right: 3px;padding: 3px 10px 1px;max-width: 100%;line-height: inherit;display: inline-block;font-weight: normal;background: rgb(128, 128, 128);color: rgb(255, 255, 255);border-top-right-radius: 3px;border-top-left-radius: 3px;box-sizing: border-box !important;overflow-wrap: break-word !important;">最后暖男我继续给你们做个小的技术总结:</span></span></h3> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">一般避免以上情况发生我们从三个时间段去分析下:</span></p> <ul class="list-paddingleft-2" style="max-width: 100%;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: 15px;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;"> <li style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-size: 15px;"><p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">事前:<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Redis</strong> 高可用,主从+哨兵,<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Redis cluster</strong>,避免全盘崩溃。</span></p></li> <li style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-size: 15px;"><p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">事中:本地 <strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">ehcache</strong> 缓存 + <strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Hystrix</strong> 限流+降级,避免<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">MySQL</strong>被打死。</span></p></li> <li style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-size: 15px;"><p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">事后:<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">Redis</strong> 持久化 <strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">RDB</strong>+<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">AOF</strong>,一旦重启,自动从磁盘上加载数据,快速恢复缓存数据。</span></p></li> </ul> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">上面的几点我会在吊打系列Redis篇全部讲一下这个月应该可以吧Redis更完,限流组件,可以设置每秒的请求,有多少能通过组件,剩余的未通过的请求,怎么办?<strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">走降级</strong>!可以返回一些默认的值,或者友情提示,或者空白的值。</span></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">好处:</strong></span></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">数据库绝对不会死,限流组件确保了每秒只有多少个请求能通过。只要数据库不死,就是说,对用户来说,3/5 的请求都是可以被处理的。只要有 3/5 的请求可以被处理,就意味着你的系统没死,对用户来说,可能就是点击几次刷不出来页面,但是多点几次,就可以刷出来一次。</span></p> <p style="margin-top: 1.7em;margin-bottom: 1.7em;max-width: 100%;min-height: 1em;color: inherit;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;letter-spacing: 2px;white-space: normal;word-spacing: 2px;background-color: rgb(255, 255, 255);line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">这个在目前主流的互联网大厂里面是最常见的,你是不是好奇,某明星爆出什么事情,你发现你去微博怎么刷都空白界面,但是有的人又直接进了,你多刷几次也出来了,现在知道了吧,那是做了降级,牺牲部分用户的体验换来服务器的安全,可还行</strong></span><span style="font-size: 15px;"><strong style="max-width: 100%;font-size: inherit;line-height: inherit;color: rgb(233, 105, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">?</strong></span></p> <section donone="shifuMouseDownCard('shifu_c_030')" label="Copyright Reserved by PLAYHUDONG." style="text-align: start;white-space: normal;margin-top: 1em;margin-bottom: 1em;caret-color: rgb(0, 0, 0);color: rgb(0, 0, 0);border-width: 0px;border-style: initial;border-color: initial;"> <section style="margin-left: 1em;line-height: 1.4;"> <span style="padding: 3px 8px;border-radius: 4px;color: rgb(255, 255, 255);background-color: rgb(255, 105, 31);font-family: inherit;text-align: inherit;text-decoration: inherit;font-size: 12px;">推荐阅读</span> <span style="margin-left: 4px;padding: 3px 8px;border-top-left-radius: 1.2em;border-top-right-radius: 1.2em;border-bottom-right-radius: 1.2em;border-bottom-left-radius: 1.2em;color: rgb(255, 255, 255);line-height: 1.2;background-color: rgb(204, 204, 204);font-family: inherit;text-align: inherit;text-decoration: inherit;border-color: rgb(249, 110, 87);font-size: 12px;">点击标题可跳转</span> </section> <section style="margin-top: -11px;padding: 22px 16px 16px;border-width: 1px;border-style: solid;border-color: rgb(255, 105, 31);color: rgb(51, 51, 51);font-size: 1em;font-family: inherit;text-align: inherit;text-decoration: inherit;"> <p><span style="font-size: 12px;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;background-color: rgb(255, 255, 255);"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MjM5NzMyMjAwMA==&mid=2651488740&idx=2&sn=61379d159fb14c0169d14d87b9252a74&chksm=bd25ed9b8a52648d72a2c04b0f67bc06101184452e694c8fd4f5ef18e77cb064c3ca56e682aa&scene=21#wechat_redirect" data-itemshowtype="11" tab="innerlink" data-linktype="2">带你100% 地了解 Redis 6.0 的客户端缓存</a><br></span></p> <p><span style="font-size: 12px;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MjM5NzMyMjAwMA==&mid=2651488445&idx=1&sn=1818e09ca19a665debfe2f3e733ee7b5&chksm=bd25ecc28a5265d45a1aa0894a2cfd601ab3edcac24496cd08ed54bd938a89dc6b2cae8dc468&scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">被 Redis 虐的日子,太惨了...</a><br></span></p> <p><span style="font-size: 12px;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MjM5NzMyMjAwMA==&mid=2651487516&idx=1&sn=90a0a4c2dd0b736f00355948066e5c7c&chksm=bd2511638a529875d4c5455f4ead117e5a425c167e2c911e6994c3fcd2e5585fba3b29c69439&scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" style="font-size: 12px;" data-linktype="2">Redis 的这些拓展方案</a></span></p> </section> </section> <p style="caret-color: rgb(0, 0, 0);color: rgb(0, 0, 0);text-align: start;white-space: normal;"><br></p> <p style="white-space: normal;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 14px;color: rgb(255, 169, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">看完本文有收获?请转发分享给更多人</span></p> <p style="white-space: normal;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;color: rgb(255, 169, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">关注「ImportNew」,提升Java技能</strong></p> <p style="white-space: normal;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><img data-ratio="0.9166666666666666" data-s="300,640" data-type="jpeg" data-w="600" width="auto" src="/upload/899866149276fa5fddb73c61ae04be64.jpg" style="box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 600px !important;"></p> <p style="text-align: right;"><span style="font-size: 14px;text-align: right;">好文章,我</span><span style="font-size: 14px;text-align: right;color: rgb(255, 41, 65);">在看</span><span style="font-size: 14px;text-align: right;">❤️</span></p> <p><br></p>
作者:微信小助手
<section data-style-type="2" data-tools="新媒体排版" data-id="1846" style="max-width: 100%;letter-spacing: 0.544px;white-space: normal;color: rgb(62, 62, 62);font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;text-size-adjust: auto;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section data-style-type="2" data-tools="新媒体排版" data-id="1846" style="max-width: 100%;letter-spacing: 0.544px;text-size-adjust: auto;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section data-style-type="2" data-tools="新媒体排版" data-id="1846" style="white-space: normal;max-width: 100%;letter-spacing: 0.544px;color: rgb(62, 62, 62);font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;text-size-adjust: auto;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section data-style-type="2" data-tools="新媒体排版" data-id="1846" style="max-width: 100%;letter-spacing: 0.544px;text-size-adjust: auto;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section style="margin-top: 10px;margin-left: 16px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <span style="max-width: 100%;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;color: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="padding: 0.2em 0.5em;max-width: 100%;background-color: rgb(159, 136, 127);border-color: rgb(159, 136, 127);border-radius: 0.3em;color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;">每日前端夜话</span></strong><strong style="max-width: 100%;color: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="margin-left: 0.3em;padding: 0.2em 0.5em;max-width: 100%;background-color: rgb(255, 255, 255);border-radius: 1.2em;border-width: 1px;border-style: solid;border-color: rgb(159, 136, 127);color: rgb(159, 136, 127);height: 1.2em;line-height: 1.2em;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></strong></span> </section> <section style="margin: -1em auto 5px;padding: 20px 10px 5px;max-width: 100%;border-radius: 0.3em;border-width: 1px;border-style: solid;border-color: rgb(159, 136, 127);background-color: rgb(239, 239, 239);box-sizing: border-box !important;overflow-wrap: break-word !important;"> <p style="max-width: 100%;min-height: 1em;color: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 15px;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></p> <p style="max-width: 100%;min-height: 1em;line-height: normal;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 12px;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">喜欢本文,点击上方“服务端思维”,关注</span></p> <p style="max-width: 100%;min-height: 1em;line-height: normal;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 12px;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">预计阅读时间:15 分钟</span></p> </section> </section> </section> <section style="letter-spacing: 0px;white-space: normal;font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;background-image: linear-gradient(90deg, rgba(50, 0, 0, 0.05) 3%, rgba(0, 0, 0, 0) 3%), linear-gradient(360deg, rgba(50, 0, 0, 0.05) 3%, rgba(0, 0, 0, 0) 3%);background-size: 20px 20px;background-position: center center;"> <p style="text-align: center;"><span style="color: rgb(0, 0, 0);font-size: 12px;background-color: rgb(239, 239, 239);letter-spacing: 0.544px;text-align: justify;"></span><br></p> <section style="max-width: 100%;background-color: rgb(255, 255, 255);letter-spacing: 0px;line-height: 1.6;background-image: linear-gradient(90deg, rgba(50, 0, 0, 0.047) 3%, rgba(0, 0, 0, 0) 3%), linear-gradient(360deg, rgba(50, 0, 0, 0.047) 3%, rgba(0, 0, 0, 0) 3%);background-size: 20px 20px;background-position: center center;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section data-style-type="6" data-tools="新媒体排版" data-id="9115" style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <section powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"> <section style="padding: 10px;max-width: 100%;box-sizing: border-box;display: inline-block;width: 677px;border-width: 1px;border-style: solid;border-color: rgb(192, 200, 209);background-color: rgb(239, 239, 239);overflow-wrap: break-word !important;"> <section powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box;font-size: 14px;overflow-wrap: break-word !important;"> <p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 12px;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">作者:Sahiti Kappagantula</span></p> <p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 12px;color: rgb(0, 0, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">翻译:疯狂的技术宅</span></p> <p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 12px;color: rgb(0, 0, 0);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;">edureka</span></span></p> </section> </section> </section> </section> </section> </section> </section> <section style="max-width: 100%;background-color: rgb(255, 255, 255);line-height: 1.6;letter-spacing: 0px;background-image: linear-gradient(90deg, rgba(50, 0, 0, 0.047) 3%, rgba(0, 0, 0, 0) 3%), linear-gradient(360deg, rgba(50, 0, 0, 0.047) 3%, rgba(0, 0, 0, 0) 3%);background-size: 20px 20px;background-position: center center;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <p style="max-width: 100%;min-height: 1em;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><img class="rich_pages" data-ratio="0.7525562372188139" data-s="300,640" data-type="jpeg" data-w="489" src="/upload/1ab63ff348329c549d107b29f70f51d5.jpg" style="box-sizing: border-box !important;overflow-wrap: break-word !important;width: 489px !important;visibility: visible !important;"></p> </section> <p style="text-align: center;"><br></p> <p style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;color: inherit;line-height: inherit;">根据 Gartner 的说法,微服务是云开发的新应用平台。微服务是独立部署和管理的,一旦应用实现在容器内,它们与底层操作系统的交互很少。因此,如果你希望把微服务添加到自己的技术栈中,并想要了解与之相关的技能,那么现在正是潜心研究的时候。为了帮你准备面试,我写出了这篇关于微服务面试题的文章。</p> <p style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;color: inherit;line-height: inherit;">在本文中,我收集了面试官最常问到的问题。</p> <h2 style="margin-top: 1.1em;margin-right: 5px;margin-bottom: 2em;padding: 8px 15px;font-weight: bold;font-size: 1.4em;line-height: inherit;letter-spacing: 2px;background-image: linear-gradient(to right bottom, rgb(0, 188, 212), rgb(63, 81, 181));background-color: rgb(63, 81, 181);color: rgb(255, 255, 255);border-left: 10px solid rgb(51, 51, 51);border-radius: 5px;text-shadow: rgb(102, 102, 102) 1px 1px 1px;box-shadow: rgb(102, 102, 102) 1px 1px 2px;"><span style="font-size: inherit;color: inherit;line-height: inherit;">微服务面试题与答案</span></h2> <h3 style="margin-top: 1.1em;margin-bottom: 1.1em;font-weight: bold;font-size: 1.3em;color: inherit;line-height: inherit;border-bottom: 2px solid rgb(0, 172, 193);"><span style="margin-right: 2px;padding-top: 3px;padding-right: 10px;padding-left: 10px;font-size: inherit;line-height: inherit;display: inline-block;font-weight: normal;background: rgb(0, 172, 193);color: rgb(255, 255, 255);border-top-right-radius: 3px;border-top-left-radius: 4px;"><strong style="font-size: inherit;color: inherit;line-height: inherit;">Q1. 说说微服务架构的优势。</strong></span></h3> <table> <thead style="font-size: inherit;color: inherit;line-height: inherit;"> <tr style="font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <th width="99" style="padding: 0.5em 1em;border-top-width: 1px;border-color: rgb(204, 204, 204);background-color: rgb(240, 240, 240);color: inherit;line-height: inherit;font-size: 1em;text-align: left;word-break: break-all;"><strong style="font-size: inherit;color: inherit;line-height: inherit;">优势</strong></th> <th width="426" style="padding: 0.5em 1em;border-top-width: 1px;border-color: rgb(204, 204, 204);background-color: rgb(240, 240, 240);color: inherit;line-height: inherit;font-size: 1em;text-align: left;"><strong style="font-size: inherit;color: inherit;line-height: inherit;">说明</strong></th> </tr> </thead> <tbody style="font-size: inherit;color: inherit;line-height: inherit;border-width: 0px;border-style: initial;border-color: initial;"> <tr style="font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td width="11" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;"><strong style="font-size: inherit;color: inherit;line-height: inherit;"><em style="font-size: inherit;color: inherit;line-height: inherit;">独立开发</em></strong></td> <td width="427" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;">所有微服务都可以根据各自的功能轻松开发</td> </tr> <tr style="font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td width="11" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;"><strong style="font-size: inherit;color: inherit;line-height: inherit;"><em style="font-size: inherit;color: inherit;line-height: inherit;">独立部署</em></strong></td> <td width="427" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;">根据他们所提供的服务,可以在任何应用中单独部署</td> </tr> <tr style="font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td width="11" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;"><strong style="font-size: inherit;color: inherit;line-height: inherit;"><em style="font-size: inherit;color: inherit;line-height: inherit;">故障隔离</em></strong></td> <td width="427" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;">即使应用中的一个服务不起作用,系统仍然继续运行</td> </tr> <tr style="font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td width="11" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;"><strong style="font-size: inherit;color: inherit;line-height: inherit;"><em style="font-size: inherit;color: inherit;line-height: inherit;">混合技术栈</em></strong></td> <td width="427" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;">可以用不同的语言和技术来构建同一应用程序的不同服务</td> </tr> <tr style="font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td width="11" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;"><strong style="font-size: inherit;color: inherit;line-height: inherit;"><em style="font-size: inherit;color: inherit;line-height: inherit;">粒度缩放</em></strong></td> <td width="427" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;">各个组件可根据需要进行扩展,无需将所有组件融合到一起</td> </tr> </tbody> </table> <h3 style="margin-top: 1.1em;margin-bottom: 1.1em;font-weight: bold;font-size: 1.3em;color: inherit;line-height: inherit;border-bottom: 2px solid rgb(0, 172, 193);"><span style="margin-right: 2px;padding-top: 3px;padding-right: 10px;padding-left: 10px;font-size: inherit;line-height: inherit;display: inline-block;font-weight: normal;background: rgb(0, 172, 193);color: rgb(255, 255, 255);border-top-right-radius: 3px;border-top-left-radius: 4px;"><strong style="font-size: inherit;color: inherit;line-height: inherit;">Q2. 你对微服务是怎么理解的?</strong></span></h3> <ul class="list-paddingleft-2" style="width: 577.422px;"> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">微服务</strong>,又名<strong style="font-size: inherit;color: inherit;line-height: inherit;">微服务架构</strong>,是一种架构风格,它将应用构建为一个小型自治服务的集合,以<strong style="font-size: inherit;color: inherit;line-height: inherit;">业务领域为模型。</strong></p></li> <li><p><span style="font-size: inherit;color: inherit;line-height: inherit;">通俗地说,就像蜜蜂通过对蜡制的等边六角形单元来构建它们的蜂巢。</span></p></li> <li><p><span style="font-size: inherit;color: inherit;line-height: inherit;">他们最初从使用各种材料的小单元开始,一点点的搭建出一个大型蜂巢。</span></p></li> <li><p><span style="font-size: inherit;color: inherit;line-height: inherit;">这些小单元组成坚固的结构,将蜂窝的特定部分固定在一起。</span></p></li> <li><p><span style="font-size: inherit;color: inherit;line-height: inherit;">这里,每个小单元都独立于另一个,但它也与其他小单元相关。</span></p></li> <li><p><span style="font-size: inherit;color: inherit;line-height: inherit;">这意味着对一个小单元的损害不会损害其他的单元,因此,蜜蜂可以在不影响完整蜂巢的情况下重建这些单元。</span></p></li> </ul> <p style="text-align: center;"><img class="rich_pages" data-ratio="0.9955257270693513" data-s="300,640" src="/upload/8020d747ec85122a282385f09d70f1a5.png" data-type="png" data-w="447"></p> <figure style="font-size: inherit;color: inherit;line-height: inherit;"> <figcaption style="margin-top: 10px;line-height: inherit;text-align: center;color: rgb(153, 153, 153);font-size: 0.7em;"> 用蜂巢表示微服务 </figcaption> </figure> <p style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;color: inherit;line-height: inherit;">请参考上图。这里,每个六边形都代表单独的服务组件。与蜜蜂的工作类似,每个敏捷团队都使用可用的框架和所选的技术栈构建单独的服务组件。就像在蜂巢中一样,这些服务组件形成一个强大的微服务架构,以提供更好的可扩展性。此外敏捷团队可以单独处理每个服务组件的问题,而不会对整个应用程序产生影响或使影响最小。</p> <h3 style="margin-top: 1.1em;margin-bottom: 1.1em;font-weight: bold;font-size: 1.3em;color: inherit;line-height: inherit;border-bottom: 2px solid rgb(0, 172, 193);"><span style="margin-right: 2px;padding-top: 3px;padding-right: 10px;padding-left: 10px;font-size: inherit;line-height: inherit;display: inline-block;font-weight: normal;background: rgb(0, 172, 193);color: rgb(255, 255, 255);border-top-right-radius: 3px;border-top-left-radius: 4px;"><strong style="font-size: inherit;color: inherit;line-height: inherit;">Q3. 微服务有哪些特点?</strong></span></h3> <p style="text-align: center;"><img class="rich_pages" data-ratio="0.5453257790368272" data-s="300,640" src="/upload/8ab99cae49d77d289266afe3253cec71.png" data-type="png" data-w="706"></p> <figure style="font-size: inherit;color: inherit;line-height: inherit;"> <figcaption style="margin-top: 10px;line-height: inherit;text-align: center;color: rgb(153, 153, 153);font-size: 0.7em;"> 微服务的特点 </figcaption> <br> </figure> <ul class="list-paddingleft-2" style="width: 577.422px;"> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">解耦(Decoupling)</strong> - 系统内的服务很大程度上是分离的。因此整个应用可以被轻松构建、修改和扩展</p></li> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">组件化(Componentization)</strong> - 微服务被视为可以被轻松替换和升级的独立组件</p></li> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">业务能力(Business Capabilities)</strong> - 微服务非常简单,专注于单一功能</p></li> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">自治(Autonomy)</strong> - 开发人员和团队可以相互独立工作,从而提高效率</p></li> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">持续交付(ContinousDelivery)</strong> - 允许频繁发版,通过系统自动化完成对软件的创建、测试和审核,</p></li> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">责任(Responsibility)</strong> - 微服务不把程序作为项目去关注。相反,他们将程序视为自己负责的产品</p></li> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">分散治理(Decentralized Governance)</strong> - 重点是用正确的工具去做正确的事。这意味着没有任何标准化模式或着技术模式。开发人员可以自由选择最合适的工具来解决自己的问题</p></li> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">敏捷性(Agility)</strong> - 微服务支持敏捷开发。任何新功能都可以快速开发并被再次丢弃</p></li> </ul> <h3 style="margin-top: 1.1em;margin-bottom: 1.1em;font-weight: bold;font-size: 1.3em;color: inherit;line-height: inherit;border-bottom: 2px solid rgb(0, 172, 193);"><span style="margin-right: 2px;padding-top: 3px;padding-right: 10px;padding-left: 10px;font-size: inherit;line-height: inherit;display: inline-block;font-weight: normal;background: rgb(0, 172, 193);color: rgb(255, 255, 255);border-top-right-radius: 3px;border-top-left-radius: 4px;"><strong style="font-size: inherit;color: inherit;line-height: inherit;">Q4. 设计微服务的最佳实践是什么?</strong></span></h3> <p style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;color: inherit;line-height: inherit;">以下是设计微服务的最佳实践:</p> <p style="text-align: center;"><img class="rich_pages" data-ratio="0.5482233502538071" data-s="300,640" src="/upload/50383e916f98af2c47ef839dd6a07991.png" data-type="png" data-w="591"></p> <figure style="font-size: inherit;color: inherit;line-height: inherit;"> <figcaption style="margin-top: 10px;line-height: inherit;text-align: center;color: rgb(153, 153, 153);font-size: 0.7em;"> 设计微服务的最佳实践 </figcaption> <br> </figure> <ol class="list-paddingleft-2" style="width: 577.422px;"> <li><p><span style="font-size: inherit;color: inherit;line-height: inherit;">为每个微服务分开数据存储</span></p></li> <li><p><span style="font-size: inherit;color: inherit;line-height: inherit;">将代码保持在类似的成熟度等级上</span></p></li> <li><p><span style="font-size: inherit;color: inherit;line-height: inherit;">为每个微服务进行单独的构建</span></p></li> <li><p><span style="font-size: inherit;color: inherit;line-height: inherit;">部署到容器中</span></p></li> <li><p><span style="font-size: inherit;color: inherit;line-height: inherit;">将服务器视为无状态的</span></p></li> </ol> <h3 style="margin-top: 1.1em;margin-bottom: 1.1em;font-weight: bold;font-size: 1.3em;color: inherit;line-height: inherit;border-bottom: 2px solid rgb(0, 172, 193);"><span style="margin-right: 2px;padding-top: 3px;padding-right: 10px;padding-left: 10px;font-size: inherit;line-height: inherit;display: inline-block;font-weight: normal;background: rgb(0, 172, 193);color: rgb(255, 255, 255);border-top-right-radius: 3px;border-top-left-radius: 4px;"><strong style="font-size: inherit;color: inherit;line-height: inherit;">Q5. 微服务架构是如何运作的?</strong></span></h3> <p style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;color: inherit;line-height: inherit;">微服务架构具有以下组件:</p> <p style="text-align: center;"><img class="rich_pages" data-ratio="0.44816883923029177" data-s="300,640" src="/upload/636df88ff2e68b4814137b5aa9b5d422.png" data-type="png" data-w="1611"></p> <figure style="font-size: inherit;color: inherit;line-height: inherit;"> <figcaption style="margin-top: 10px;line-height: inherit;text-align: center;color: rgb(153, 153, 153);font-size: 0.7em;"> 微服务架构 </figcaption> </figure> <ul class="list-paddingleft-2" style="width: 577.422px;"> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">Clients</strong> – 来自不同设备的不同用户发送请求。</p></li> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">Identity Providers</strong> – 对用户或客户端身份进行身份验证,并颁发安全令牌。</p></li> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">API Gateway</strong> – 处理客户端请求。</p></li> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">Static Content</strong> – 容纳系统的所有内容。</p></li> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">Management</strong> – 平衡节点上的服务压力并识别故障。</p></li> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">Service Discovery</strong> – 用于找到微服务之间通信路径的向导。</p></li> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">Content Delivery Networks</strong> – 代理服务器及其数据中心的分布式网络。</p></li> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">Remote Service</strong> – 启用驻留在 IT 设备网络上的远程访问信息。</p></li> </ul> <h3 style="margin-top: 1.1em;margin-bottom: 1.1em;font-weight: bold;font-size: 1.3em;color: inherit;line-height: inherit;border-bottom: 2px solid rgb(0, 172, 193);"><span style="margin-right: 2px;padding-top: 3px;padding-right: 10px;padding-left: 10px;font-size: inherit;line-height: inherit;display: inline-block;font-weight: normal;background: rgb(0, 172, 193);color: rgb(255, 255, 255);border-top-right-radius: 3px;border-top-left-radius: 4px;"><strong style="font-size: inherit;color: inherit;line-height: inherit;">Q6. 微服务架构的优点和缺点是什么?</strong></span></h3> <table> <thead style="font-size: inherit;color: inherit;line-height: inherit;"> <tr style="font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <th width="222" style="padding: 0.5em 1em;border-top-width: 1px;border-color: rgb(204, 204, 204);background-color: rgb(240, 240, 240);color: inherit;line-height: inherit;font-size: 1em;text-align: left;"><strong style="font-size: inherit;color: inherit;line-height: inherit;">微服务架构的优点</strong></th> <th width="307" style="padding: 0.5em 1em;border-top-width: 1px;border-color: rgb(204, 204, 204);background-color: rgb(240, 240, 240);color: inherit;line-height: inherit;font-size: 1em;text-align: left;"><strong style="font-size: inherit;color: inherit;line-height: inherit;">微服务架构的缺点</strong></th> </tr> </thead> <tbody style="font-size: inherit;color: inherit;line-height: inherit;border-width: 0px;border-style: initial;border-color: initial;"> <tr style="font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td width="186" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;">可以自由使用不同的技术</td> <td width="307" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;">增加故障排除的难度</td> </tr> <tr style="font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td width="186" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;">每个微服务都专注于单一功能</td> <td width="307" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;">由于远程调用而导致延迟增加</td> </tr> <tr style="font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td width="186" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;">支持单个可部署单元</td> <td width="307" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;">增加配置和其他操作的工作量</td> </tr> <tr style="font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td width="186" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;">允许软件的持续发布</td> <td width="307" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;">难以维持处理的安全性</td> </tr> <tr style="font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td width="186" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;">可确保每项服务的安全性</td> <td width="307" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;">很难跟踪各种边界的数据</td> </tr> <tr style="font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <td width="186" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;">并行开发和部署多个服务</td> <td width="307" style="padding: 0.5em 1em;border-color: rgb(204, 204, 204);color: inherit;line-height: inherit;font-size: 1em;">服务之间难以编码</td> </tr> </tbody> </table> <h3 style="margin-top: 1.1em;margin-bottom: 1.1em;font-weight: bold;font-size: 1.3em;color: inherit;line-height: inherit;border-bottom: 2px solid rgb(0, 172, 193);"><span style="margin-right: 2px;padding-top: 3px;padding-right: 10px;padding-left: 10px;font-size: inherit;line-height: inherit;display: inline-block;font-weight: normal;background: rgb(0, 172, 193);color: rgb(255, 255, 255);border-top-right-radius: 3px;border-top-left-radius: 4px;"><strong style="font-size: inherit;color: inherit;line-height: inherit;">Q7. 单体应用、SOA 和微服务架构有什么区别?</strong></span></h3> <p style="text-align: center;"><img class="rich_pages" data-ratio="0.6413255360623782" data-s="300,640" src="/upload/1f129544ab3cf426fe9131751a4ccb04.png" data-type="png" data-w="513"></p> <figure style="font-size: inherit;color: inherit;line-height: inherit;"> <figcaption style="margin-top: 10px;line-height: inherit;text-align: center;color: rgb(153, 153, 153);font-size: 0.7em;"> 单体应用、SOA与微服务之间的比较 </figcaption> <br> </figure> <ul class="list-paddingleft-2" style="width: 577.422px;"> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">单体应用</strong>类似于一个大容器,其中程序的所有组件都被组装在一起并紧密包装。</p></li> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">SOA</strong>是一组相互通信的服务。通信可以涉及简单的数据传送,也可以涉及两个或多个协调某些活动的服务。</p></li> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">微服务架构</strong>是一种架构风格,它将应用程序构建为以业务域为模型的小型自治服务集合。</p></li> </ul> <h3 style="margin-top: 1.1em;margin-bottom: 1.1em;font-weight: bold;font-size: 1.3em;color: inherit;line-height: inherit;border-bottom: 2px solid rgb(0, 172, 193);"><span style="margin-right: 2px;padding-top: 3px;padding-right: 10px;padding-left: 10px;font-size: inherit;line-height: inherit;display: inline-block;font-weight: normal;background: rgb(0, 172, 193);color: rgb(255, 255, 255);border-top-right-radius: 3px;border-top-left-radius: 4px;"><strong style="font-size: inherit;color: inherit;line-height: inherit;">Q8. 在使用微服务架构时,你面临的挑战是什么?</strong></span></h3> <p style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;color: inherit;line-height: inherit;">开发较小的微服务听起来很容易,但在开发时会经常遇到一些挑战。</p> <ul class="list-paddingleft-2" style="width: 577.422px;"> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">自动化组件</strong>:难以自动化,因为有许多较小的组件。对于每个组件,都必须采取构建、发布和监控的步骤。</p></li> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">可感知性</strong>:将大量组件维持在一起会带来难以部署、维护、监控和识别的问题。它需要在所有组件周围具有很好的感知能力。</p></li> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">配置管理</strong>:有时在各种环境中维护组件的配置会很困难。</p></li> <li><p><strong style="font-size: inherit;color: inherit;line-height: inherit;">调试</strong>:很难找到与产生的错误相关的每一项服务。维护一个集中式的日志和控制面板对调试问题至关重要。</p></li> </ul> <h3 style="margin-top: 1.1em;margin-bottom: 1.1em;font-weight: bold;font-size: 1.3em;color: inherit;line-height: inherit;border-bottom: 2px solid rgb(0, 172, 193);"><span style="margin-right: 2px;padding-top: 3px;padding-right: 10px;padding-left: 10px;font-size: inherit;line-height: inherit;display: inline-block;font-weight: normal;background: rgb(0, 172, 193);color: rgb(255, 255, 255);border-top-right-radius: 3px;border-top-left-radius: 4px;"><strong style="font-size: inherit;color: inherit;line-height: inherit;">Q9. SOA 和微服务架构之间的主要区别是什么?</strong></span></h3> <p style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;color: inherit;line-height: inherit;">SOA 和微服务之间的主要区别如下:</p> <table> <thead style="font-size: inherit;color: inherit;line-height: inherit;"> <tr style="font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-right-style: initial;border-bottom-style: initial;border-left-style: initial;border-right-color: initial;border-bottom-color: initial;border-left-color: initial;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;"> <th width="217" style="padding: 0.5em 1em;border-top-width: 1px;border-color: rgb(204, 204, 204);background-color: rgb(240, 240, 240);color: inherit;line-height: inherit;font-size: 1em;text-align: left;word-break: break-all;"><strong style="font-size: inherit;color: inherit;line-height: inherit;">SOA</strong></th> <th width="307" style="padding: 0.5em 1em;border-top-width: 1px;border-color: rgb(204, 204, 204);background-color: rgb(240, 240, 240);color: inherit;line-height: inherit;font-size: 1em;text-align: left;"><strong style="font-size: inherit;color: inherit;line-height: inherit;">微服�
作者:微信小助手
<section style="display: none;" data-tools="新媒体管家" data-label="powered by xmt.cn" data-mpa-powered-by="yiban.io"> <br> </section> <p style="text-align: center;"><span style="font-size: 13px;color: rgb(136, 136, 136);font-family: Georgia, "Times New Roman", Times, "Songti SC", serif;letter-spacing: 0.544px;">点击上方蓝色“</span><span style="font-size: 13px;font-family: Georgia, "Times New Roman", Times, "Songti SC", serif;letter-spacing: 0.544px;color: rgb(0, 128, 255);">程序猿DD</span><span style="font-size: 13px;color: rgb(136, 136, 136);font-family: Georgia, "Times New Roman", Times, "Songti SC", serif;letter-spacing: 0.544px;">”,选择“设为星标”</span><strong style="max-width: 100%;letter-spacing: 0.544px;color: rgb(74, 74, 74);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;font-size: 16px;white-space: pre-line;background-color: rgb(255, 255, 255);text-align: right;box-sizing: border-box !important;overflow-wrap: break-word !important;"></strong></p> <p style="max-width: 100%;min-height: 1em;white-space: normal;text-align: center;overflow-wrap: break-word !important;box-sizing: border-box !important;"><span style="max-width: 100%;font-size: 13px;overflow-wrap: break-word !important;box-sizing: border-box !important;"><span style="max-width: 100%;color: rgb(136, 136, 136);font-family: Georgia, "Times New Roman", Times, "Songti SC", serif;letter-spacing: 0.544px;overflow-wrap: break-word !important;box-sizing: border-box !important;">回复“</span><span style="max-width: 100%;font-family: Georgia, "Times New Roman", Times, "Songti SC", serif;letter-spacing: 0.544px;color: rgb(0, 128, 255);overflow-wrap: break-word !important;box-sizing: border-box !important;">资源</span><span style="max-width: 100%;color: rgb(136, 136, 136);font-family: Georgia, "Times New Roman", Times, "Songti SC", serif;letter-spacing: 0.544px;overflow-wrap: break-word !important;box-sizing: border-box !important;">”获取独家整理的学习资料!</span></span></p> <p style="margin-top: 10px;margin-bottom: 10px;max-width: 100%;min-height: 1em;white-space: normal;text-align: center;overflow-wrap: break-word !important;box-sizing: border-box !important;"><span style="max-width: 100%;color: rgb(136, 136, 136);font-family: Georgia, "Times New Roman", Times, "Songti SC", serif;font-size: 14px;letter-spacing: 0.544px;overflow-wrap: break-word !important;box-sizing: border-box !important;"><img data-backh="34" data-backw="540" data-ratio="0.0625" data-s="300,640" data-type="jpeg" data-w="640" width="100%" src="/upload/8c292e55ba5a23cb6ebc11f2a2c4fece.jpg" style="font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;overflow-wrap: break-word !important;box-sizing: border-box !important;visibility: visible !important;width: 654px !important;"></span></p> <section style="margin-left: 8px;margin-right: 8px;"> <span style="font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: 13px;color: rgb(178, 178, 178);">作者 | 六点半起床</span> </section> <section style="margin-left: 8px;margin-right: 8px;"> <span style="font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;font-size: 13px;color: rgb(178, 178, 178);">来源 | juejin.im/post/6854573211426750472</span> </section> <p style="max-width: 100%;min-height: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;"><br></p> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="padding-right: 10px;padding-left: 10px;white-space: normal;background-color: rgb(255, 255, 255);font-size: 16px;color: black;line-height: 1.6;letter-spacing: 0px;word-break: break-word;text-align: left;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;"> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">大家都知道okhttp是一款由square公司开源的java版本http客户端工具。实际上,square公司还开源了基于okhttp进一步封装的retrofit工具,用来支持通过接口的方式发起http请求。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">如果你的项目中还在直接使用RestTemplate或者okhttp,或者基于它们封装的HttpUtils,那么你可以尝试使用Retrofit。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;"><code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">retrofit-spring-boot-starter</code>实现了Retrofit与spring-boot框架快速整合,并且支持了部分功能增强,从而极大的简化spring-boot项目下http接口调用开发。接下来我们直接通过ret<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">rofit-spring-boot-starter</code>,来看看spring-boot项目发送http请求有多简单。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">retrofit官方并没有提供与spring-boot快速整合的starter。<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">retrofit-spring-boot-starter</code>是笔者封装的,已在生产环境使用,非常稳定。喜欢的话给个star。</p> <blockquote data-tool="mdnice编辑器" style="margin-top: 20px;margin-bottom: 20px;padding: 10px 10px 10px 20px;border-left-color: rgb(239, 112, 96);color: rgb(106, 115, 125);font-size: 0.9em;overflow: auto;background: rgb(255, 249, 249);"> <p style="padding-top: 8px;padding-bottom: 8px;font-size: 16px;color: black;line-height: 26px;">https://github.com/LianjiaTech/retrofit-spring-boot-starter</p> </blockquote> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;">引入依赖</h3> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="margin-bottom: -7px;display: block;background: url("https://mmbiz.qpic.cn/mmbiz_png/eQPyBffYbud9I2iaWtUEjWbjBmlluuV8cW5pLjRvlmmpYjK6NrF9lcUptj0ZoP4MLjsnuhOg1TtxQW5Fkoqetpw/640?wx_fmt=png") 10px 10px / 40px no-repeat rgb(250, 250, 250);height: 30px;width: 657px;border-radius: 5px;"></span><code style="padding: 15px 16px 16px;overflow-x: auto;color: rgb(56, 58, 66);display: -webkit-box;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;font-size: 12px;background: rgb(250, 250, 250);border-radius: 5px;"><span style="line-height: 26px;"><<span style="color: rgb(228, 86, 73);line-height: 26px;">dependency</span>></span><br> <span style="line-height: 26px;"><<span style="color: rgb(228, 86, 73);line-height: 26px;">groupId</span>></span>com.github.lianjiatech<span style="line-height: 26px;"></<span style="color: rgb(228, 86, 73);line-height: 26px;">groupId</span>></span><br> <span style="line-height: 26px;"><<span style="color: rgb(228, 86, 73);line-height: 26px;">artifactId</span>></span>retrofit-spring-boot-starter<span style="line-height: 26px;"></<span style="color: rgb(228, 86, 73);line-height: 26px;">artifactId</span>></span><br> <span style="line-height: 26px;"><<span style="color: rgb(228, 86, 73);line-height: 26px;">version</span>></span>2.0.2<span style="line-height: 26px;"></<span style="color: rgb(228, 86, 73);line-height: 26px;">version</span>></span><br><span style="line-height: 26px;"></<span style="color: rgb(228, 86, 73);line-height: 26px;">dependency</span>></span><br></code></pre> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;">配置@RetrofitScan注解</h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">你可以给带有 @Configuration 的类配置@RetrofitScan,或者直接配置到spring-boot的启动类上,如下:</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="margin-bottom: -7px;display: block;background: url("https://mmbiz.qpic.cn/mmbiz_png/eQPyBffYbud9I2iaWtUEjWbjBmlluuV8cW5pLjRvlmmpYjK6NrF9lcUptj0ZoP4MLjsnuhOg1TtxQW5Fkoqetpw/640?wx_fmt=png") 10px 10px / 40px no-repeat rgb(250, 250, 250);height: 30px;width: 657px;border-radius: 5px;"></span><code style="padding: 15px 16px 16px;overflow-x: auto;color: rgb(56, 58, 66);display: -webkit-box;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;font-size: 12px;background: rgb(250, 250, 250);border-radius: 5px;"><span style="color: rgb(64, 120, 242);line-height: 26px;">@SpringBootApplication</span><br><span style="color: rgb(64, 120, 242);line-height: 26px;">@RetrofitScan</span>(<span style="color: rgb(80, 161, 79);line-height: 26px;">"com.github.lianjiatech.retrofit.spring.boot.test"</span>)<br><span style="color: rgb(166, 38, 164);line-height: 26px;">public</span> <span style="line-height: 26px;"><span style="color: rgb(166, 38, 164);line-height: 26px;">class</span> <span style="color: rgb(193, 132, 1);line-height: 26px;">RetrofitTestApplication</span> </span>{<br><br> <span style="line-height: 26px;"><span style="color: rgb(166, 38, 164);line-height: 26px;">public</span> <span style="color: rgb(166, 38, 164);line-height: 26px;">static</span> <span style="color: rgb(166, 38, 164);line-height: 26px;">void</span> <span style="color: rgb(64, 120, 242);line-height: 26px;">main</span><span style="line-height: 26px;">(String[] args)</span> </span>{<br> SpringApplication.run(RetrofitTestApplication.class, args);<br> }<br>}<br></code></pre> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;">定义http接口</h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">接口必须使用@RetrofitClient注解标记!推荐:<a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzIyNDU2ODA4OQ==&mid=2247484532&idx=1&sn=1c243934507d79db4f76de8ed0e5727f&chksm=e80db202df7a3b14fe7077b0fe5ec4de4088ce96a2cde16cbac21214956bd6f2e8f51193ee2b&scene=21#wechat_redirect" textvalue="一百期面试题汇总" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="color: rgb(0, 0, 0);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;font-variant-numeric: normal;font-variant-east-asian: normal;line-height: 26px;widows: 1;">一百期面试题汇总</a></p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">http相关注解可参考官方文档:</p> <blockquote data-tool="mdnice编辑器" style="margin-top: 20px;margin-bottom: 20px;padding: 10px 10px 10px 20px;border-left-color: rgb(239, 112, 96);color: rgb(106, 115, 125);font-size: 0.9em;overflow: auto;background: rgb(255, 249, 249);"> <p style="padding-top: 8px;padding-bottom: 8px;font-size: 16px;color: black;line-height: 26px;">https://square.github.io/retrofit/</p> </blockquote> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="margin-bottom: -7px;display: block;background: url("https://mmbiz.qpic.cn/mmbiz_png/eQPyBffYbud9I2iaWtUEjWbjBmlluuV8cW5pLjRvlmmpYjK6NrF9lcUptj0ZoP4MLjsnuhOg1TtxQW5Fkoqetpw/640?wx_fmt=png") 10px 10px / 40px no-repeat rgb(250, 250, 250);height: 30px;width: 657px;border-radius: 5px;"></span><code style="padding: 15px 16px 16px;overflow-x: auto;color: rgb(56, 58, 66);display: -webkit-box;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;font-size: 12px;background: rgb(250, 250, 250);border-radius: 5px;"><span style="color: rgb(64, 120, 242);line-height: 26px;">@RetrofitClient</span>(baseUrl = <span style="color: rgb(80, 161, 79);line-height: 26px;">"${test.baseUrl}"</span>)<br><span style="color: rgb(166, 38, 164);line-height: 26px;">public</span> <span style="line-height: 26px;"><span style="color: rgb(166, 38, 164);line-height: 26px;">interface</span> <span style="color: rgb(193, 132, 1);line-height: 26px;">HttpApi</span> </span>{<br><br> <span style="color: rgb(64, 120, 242);line-height: 26px;">@GET</span>(<span style="color: rgb(80, 161, 79);line-height: 26px;">"person"</span>)<br> <span style="line-height: 26px;">Result<Person> <span style="color: rgb(64, 120, 242);line-height: 26px;">getPerson</span><span style="line-height: 26px;">(@Query(<span style="color: rgb(80, 161, 79);line-height: 26px;">"id"</span>)</span> Long id)</span>;<br>}<br></code></pre> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;">注入使用</h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">将接口注入到其它Service中即可使用。</p> <pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"><span style="margin-bottom: -7px;display: block;background: url("https://mmbiz.qpic.cn/mmbiz_png/eQPyBffYbud9I2iaWtUEjWbjBmlluuV8cW5pLjRvlmmpYjK6NrF9lcUptj0ZoP4MLjsnuhOg1TtxQW5Fkoqetpw/640?wx_fmt=png") 10px 10px / 40px no-repeat rgb(250, 250, 250);height: 30px;width: 657px;border-radius: 5px;"></span><code style="padding: 15px 16px 16px;overflow-x: auto;color: rgb(56, 58, 66);display: -webkit-box;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;font-size: 12px;background: rgb(250, 250, 250);border-radius: 5px;"><span style="color: rgb(64, 120, 242);line-height: 26px;">@Service</span><br><span style="color: rgb(166, 38, 164);line-height: 26px;">public</span> <span style="line-height: 26px;"><span style="color: rgb(166, 38, 164);line-height: 26px;">class</span> <span style="color: rgb(193, 132, 1);line-height: 26px;">TestService</span> </span>{<br><br> <span style="color: rgb(64, 120, 242);line-height: 26px;">@Autowired</span><br> <span style="color: rgb(166, 38, 164);line-height: 26px;">private</span> HttpApi httpApi;<br><br> <span style="line-height: 26px;"><span style="color: rgb(166, 38, 164);line-height: 26px;">public</span> <span style="color: rgb(166, 38, 164);line-height: 26px;">void</span> <span style="color: rgb(64, 120, 242);line-height: 26px;">test</span><span style="line-height: 26px;">()</span> </span>{<br> <span style="color: rgb(160, 161, 167);font-style: italic;line-height: 26px;">// 通过httpApi发起http请求</span><br> }<br>}<br></code></pre> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">只要通过上述几个步骤,就能实现通过接口发送http请求了,真的很简单。如果你在spring-boot项目里面使用过mybatis,相信你对这种使用方式会更加熟悉。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">接下来我们继续介绍一下<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(239, 112, 96);">retrofit-spring-boot-starter</code>更高级一点的功能。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;">注解式拦截器</h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">很多时候,我们希望某个接口下的某些http请求执行统一的拦截处理逻辑。这个时候可以使用注解式拦截器。使用的步骤主要分为2步:</p> <ul data-tool="mdnice编辑器" class="list-paddingleft-2" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 继承BasePathMatchInterceptor编写拦截处理器; </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> 接口�
作者:微信小助手
<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="padding-right: 10px;padding-left: 10px;line-height: 1.6;word-break: break-word;text-align: left;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 15px;letter-spacing: 0.05em;" data-mpa-powered-by="yiban.io"> <p style="text-align: center;"><img class="rich_pages" data-backh="314" data-backw="558" data-ratio="0.5625" data-s="300,640" src="/upload/980f447c4c2000f1336b17a9a81f7440.jpg" data-type="jpeg" data-w="640" style="width: 100%;height: auto;"></p> <p style="text-align: right;"><span style="font-size: 13px;">_陈哈哈|https://sourl.cn/kKbzpH</span></p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">记得去年我在往MySQL存入emoji表情😲😳时,一直出错,无法导入。后来找到办法 -- 通过把 <strong style="color: rgb(70, 51, 118);">utf8</strong> 改成 <strong style="color: rgb(70, 51, 118);">utf8mb4</strong> 就可以了,并没有深究。<br></p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">一年后,我看到一篇文章讲到emoji文字占4个字节,通常要用utf-8去接收才行,其他编码可能会出错。我突然想到去年操作MySQL把utf8改成utf8mb4的事儿。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">嗯?他本身不就是utf8编码么!那我当时还改个锤子?</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">难道,MySQL的utf8不是真正的UTF-8编码吗??! 卧槽这。。MySQL有bug!</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">带着疑问查询了很多相关材料,才发现这竟然是MySQL的一个历史遗留问题~~ 我笑了,没想到这么牛B的MySQL也会有这段往事。</p> <h2 data-tool="mdnice编辑器" style="margin: 1em auto;padding-top: 0.5em;padding-bottom: 0.5em;font-weight: bold;font-size: 22px;min-height: 32px;line-height: 28px;color: rgb(70, 51, 118);border-bottom: 1px solid rgb(70, 51, 118);border-top-color: rgb(70, 51, 118);border-right-color: rgb(70, 51, 118);border-left-color: rgb(70, 51, 118);text-align: center;width: 474.297px;display: flex;flex-direction: column;justify-content: center;">一、报错回顾</h2> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">将emoji文字直接写入SQL中,执行 insert 语句报错;</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="sql"><code style="white-space: pre-wrap;border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">INSERT INTO `csjdemo`.`student` (`ID`, `NAME`, `SEX`, `AGE`, `CLASS`, `GRADE`, `HOBBY`) </span></code><code style="white-space: pre-wrap;border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">VALUES ('20', '陈哈哈😓', '男', '20', '181班', '9年级', '看片儿');</span></code></pre> </section> <blockquote data-tool="mdnice编辑器" style="margin: 10px 5px;padding: 10px 10px 10px 20px;border-left-color: rgb(150, 84, 181);color: rgb(97, 97, 97);font-size: 0.9em;overflow: auto;border-right: 1px solid rgb(150, 84, 181);quotes: none;background: rgb(251, 249, 253);"> <p style="padding-top: 8px;padding-bottom: 8px;font-size: 16px;color: black;line-height: 26px;">[Err] 1366 - Incorrect string value: '\xF0\x9F\x98\x93' for column 'NAME' at row 1</p> </blockquote> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">改了数据库编码、系统编码以及表字段的编码格式 → <strong style="color: rgb(70, 51, 118);">utf8mb4</strong> 之后,就可以了:</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="sql"><code style="white-space: pre-wrap;border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">INSERT INTO `student` (`ID`, `NAME`, `SEX`, `AGE`, `CLASS`, `GRADE`, `HOBBY`) </span></code><code style="white-space: pre-wrap;border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">VALUES (null, '陈哈哈😓😓', '男', '20', '181班', '9年级', '看片儿');</span></code></pre> </section> <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.5370705244122965" src="/upload/71e9eb6b8e0e4a2fc46e6249a1b7cb0e.png" data-type="png" data-w="553" style="margin-right: auto;margin-left: auto;display: block;"> </figure> <h2 data-tool="mdnice编辑器" style="margin: 1em auto;padding-top: 0.5em;padding-bottom: 0.5em;font-weight: bold;font-size: 22px;min-height: 32px;line-height: 28px;color: rgb(70, 51, 118);border-bottom: 1px solid rgb(70, 51, 118);border-top-color: rgb(70, 51, 118);border-right-color: rgb(70, 51, 118);border-left-color: rgb(70, 51, 118);text-align: center;width: 474.297px;display: flex;flex-direction: column;justify-content: center;">二、MySQL中utf8的趣事</h2> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;"><strong style="color: rgb(70, 51, 118);">MySQL 的“utf8”实际上不是真正的 UTF-8。</strong></p> <blockquote data-tool="mdnice编辑器" style="margin: 10px 5px;padding: 10px 10px 10px 20px;border-left-color: rgb(150, 84, 181);color: rgb(97, 97, 97);font-size: 0.9em;overflow: auto;border-right: 1px solid rgb(150, 84, 181);quotes: none;background: rgb(251, 249, 253);"> <p style="padding-top: 8px;padding-bottom: 8px;font-size: 16px;color: black;line-height: 26px;"><strong style="color: rgb(70, 51, 118);">在MySQL中,“utf8”编码只支持每个字符最多三个字节,而真正的 UTF-8 是每个字符最多四个字节。</strong></p> </blockquote> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">在utf8编码中,中文是占3个字节,其他数字、英文、符号占一个字节。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">但emoji符号占4个字节,一些较复杂的文字、繁体字也是4个字节。所以导致写入失败,应该改成<strong style="color: rgb(70, 51, 118);">utf8mb4。</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.5705950991831972" src="/upload/dcd84c4f612f86ff34ea71369edf2262.png" data-type="png" data-w="857" style="margin-right: auto;margin-left: auto;display: block;"> </figure> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">如上图中所示,这是编码改成utf8mb4后入库的数据,大家可以清晰的对比一下所占的字符数、字节数。正因如此,4字节的内容往utf8编码中插入,肯定是不行的,插不进去啊,是吧(大潘摊手)。</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" src="/upload/4166f9252e35bb340d5ed8ddd824b47f.jpg" data-type="jpeg" data-w="690" style="margin-right: auto;margin-left: auto;display: block;"> </figure> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">MySQL 一直没有修复这个 bug,他们在 2010 年发布了一个叫作“utf8mb4”的字符集,巧妙的绕过了这个问题。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">当然,他们并没有对新的字符集广而告之(可能是因为这个 bug 让他们觉得很尴尬),以致于现在网络上仍然在建议开发者使用“utf8”,但这些建议都是错误的。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 1.2em;margin-bottom: 1em;padding-left: 10px;font-weight: bold;font-size: 20px;color: rgb(70, 51, 118);border-left: 2px solid rgb(70, 51, 118);">1. utf8mb4 才是真正的UTF-8</h3> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;"><strong style="color: rgb(70, 51, 118);">是的,MySQL 的“utf8mb4”才是真正的“UTF-8”。</strong></p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">MySQL 的“utf8”是一种“专属的编码”,它能够编码的 Unicode 字符并不多。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">在这里Mark一下:<strong style="color: rgb(70, 51, 118);">所有在使用“utf8”的 MySQL 和 MariaDB 用户都应该改用“utf8mb4”,永远都不要再使用“utf8”。</strong></p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">那么什么是编码?什么是 UTF-8?</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">我们都知道,计算机使用 0 和 1 来存储文本。比如字符“C”被存成“01000011”,那么计算机在显示这个字符时需要经过两个步骤:</p> <ol data-tool="mdnice编辑器" class="list-paddingleft-2" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;width: 557.438px;color: black;"> <li> <section style="margin-top: 10px;margin-bottom: 10px;line-height: 26px;color: rgb(1, 1, 1);"> 计算机读取“01000011”,得到数字 67,因为 67 被编码成“01000011”。 </section></li> <li> <section style="margin-top: 10px;margin-bottom: 10px;line-height: 26px;color: rgb(1, 1, 1);"> 计算机在 Unicode 字符集中查找 67,找到了“C”。 </section></li> </ol> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">同样的:</p> <ol data-tool="mdnice编辑器" class="list-paddingleft-2" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;width: 557.438px;color: black;"> <li> <section style="margin-top: 10px;margin-bottom: 10px;line-height: 26px;color: rgb(1, 1, 1);"> 我的电脑将“C”映射成 Unicode 字符集中的 67。 </section></li> <li> <section style="margin-top: 10px;margin-bottom: 10px;line-height: 26px;color: rgb(1, 1, 1);"> 我的电脑将 67 编码成“01000011”,并发送给 Web 服务器。 </section></li> </ol> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">几乎所有的网络应用都使用了 Unicode 字符集,因为没有理由使用其他字符集。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">Unicode 字符集包含了上百万个字符。最简单的编码是 UTF-32,每个字符使用 32 位。这样做最简单,因为一直以来,计算机将 32 位视为数字,而计算机最在行的就是处理数字。但问题是,这样太浪费空间了。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">UTF-8 可以节省空间,在 UTF-8 中,字符“C”只需要 8 位,一些不常用的字符,比如“😓”需要 32 位。其他的字符可能使用 16 位或 24 位。一篇类似本文这样的文章,如果使用 UTF-8 编码,占用的空间只有 UTF-32 的四分之一左右。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 1.2em;margin-bottom: 1em;padding-left: 10px;font-weight: bold;font-size: 20px;color: rgb(70, 51, 118);border-left: 2px solid rgb(70, 51, 118);">2. utf8 的简史</h3> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;"><strong style="color: rgb(70, 51, 118);">为什么 MySQL 开发者会让“utf8”失效?</strong> 我们或许可以从MySQL版本提交日志中寻找答案。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">MySQL 从 4.1 版本开始支持 UTF-8,也就是 2003 年,而今天使用的 UTF-8 标准(RFC 3629)是随后才出现的。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">旧版的 UTF-8 标准(RFC 2279)最多支持每个字符 6 个字节。2002 年 3 月 28 日,MySQL 开发者在第一个 MySQL 4.1 预览版中使用了 RFC 2279。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">同年 9 月,他们对 MySQL 源代码进行了一次调整:“UTF8 现在最多只支持 3 个字节的序列”。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">是谁提交了这些代码?他为什么要这样做?这个问题不得而知。在迁移到 Git 后(MySQL 最开始使用的是 BitKeeper),MySQL 代码库中的很多提交者的名字都丢失了。2003 年 9 月的邮件列表中也找不到可以解释这一变更的线索。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">不过我们可以试着猜测一下:</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">2002年,MySQL做出了一个决定:如果用户可以保证数据表的每一行都使用相同的字节数,那么 MySQL 就可以在性能方面来一个大提升。为此,用户需要将文本列定义为“CHAR”,每个“CHAR”列总是拥有相同数量的字符。如果插入的字符少于定义的数量,MySQL 就会在后面填充空格,如果插入的字符超过了定义的数量,后面超出部分会被截断。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">MySQL 开发者在最开始尝试 UTF-8 时使用了每个字符6个字节,CHAR(1) 使用6个字节,CHAR(2)使用12个字节,并以此类推。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">应该说,他们最初的行为才是正确的,可惜这一版本一直没有发布。但是文档上却这么写了,而且广为流传,所有了解 UTF-8 的人都认同文档里写的东西。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">不过很显然,MySQL 开发者或厂商担心会有用户做这两件事:</p> <ul data-tool="mdnice编辑器" class="list-paddingleft-2" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;width: 557.438px;color: black;"> <li> <section style="margin-top: 10px;margin-bottom: 10px;line-height: 26px;color: rgb(1, 1, 1);"> 使用 CHAR 定义列(在现在看来,CHAR 已经是老古董了,但在那时,在 MySQL 中使用 CHAR 会更快,不过从 2005 年以后就不是这样子了)。 </section></li> <li> <section style="margin-top: 10px;margin-bottom: 10px;line-height: 26px;color: rgb(1, 1, 1);"> 将 CHAR 列的编码设置为“utf8”。 </section></li> </ul> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">我的猜测是 MySQL 开发者本来想帮助那些希望在空间和速度上双赢的用户,但他们搞砸了“utf8”编码。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">所以结果就是没有赢家。那些希望在空间和速度上双赢的用户,当他们在使用“utf8”的 CHAR 列时,实际上使用的空间比预期的更大,速度也比预期的慢。而想要正确性的用户,当他们使用“utf8”编码时,却无法保存像“😓”这样的字符,因为“😓”是4个字节的。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">在这个不合法的字符集发布了之后,MySQL 就无法修复它,因为这样需要要求所有用户重新构建他们的数据库。最终,<strong style="color: rgb(70, 51, 118);">MySQL 在 2010 年重新发布了“utf8mb4”来支持真正的 UTF-8。</strong></p> <h2 data-tool="mdnice编辑器" style="margin: 1em auto;padding-top: 0.5em;padding-bottom: 0.5em;font-weight: bold;font-size: 22px;min-height: 32px;line-height: 28px;color: rgb(70, 51, 118);border-bottom: 1px solid rgb(70, 51, 118);border-top-color: rgb(70, 51, 118);border-right-color: rgb(70, 51, 118);border-left-color: rgb(70, 51, 118);text-align: center;width: 474.297px;display: flex;flex-direction: column;justify-content: center;">三、总结</h2> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">主要是目前网络上几乎所有的文章都把 “utf8” 当成是真正的 UTF-8,包括之前我写的文章以及做的项目(捂脸);因此希望更多的朋友能够看到这篇文章。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">相信还有很多跟我在同一条船上的人,这是必然的。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-size: 16px;line-height: 26px;color: black;">所以,<strong style="color: rgb(70, 51, 118);">大家以后再搭建MySQL、MariaDB数据库时,记得将数据库相应编码都改为utf8mb4。</strong>终有一天,接你班儿的程序员发或你的领导现这个问题后,一定会在心里默默感到你的技术牛B。</p> </section> <p><br style="white-space: normal;"></p> <h2 data-tool="mdnice编辑器" style="margin: 1em auto;padding-top: 0.5em;padding-bottom: 0.5em;font-weight: bold;font-size: 22px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;letter-spacing: 0.75px;white-space: normal;background-color: rgb(255, 255, 255);min-height: 32px;line-height: 28px;color: rgb(70, 51, 118);border-bottom: 1px solid rgb(70, 51, 118);border-top-color: rgb(70, 51, 118);border-right-color: rgb(70, 51, 118);border-left-color: rgb(70, 51, 118);text-align: center;width: 558.438px;display: flex;flex-direction: column;justify-content: center;">最后</h2> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;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);font-size: 16px;line-height: 26px;color: black;"><span style="letter-spacing: 0.05em;">文章有帮助可以点个「</span><strong style="letter-spacing: 0.05em;color: rgb(70, 51, 118);">在看</strong><span style="letter-spacing: 0.05em;">」或「</span><strong style="letter-spacing: 0.05em;color: rgb(70, 51, 118);">分享」</strong><span style="letter-spacing: 0.05em;">,都是支持,我都喜欢!</span><br></p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;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);font-size: 16px;line-height: 26px;color: black;"><em style="color: rgb(227, 92, 51);">我是Guide哥,Java后端开发,会一点前端知识,喜欢烹饪,自由的少年。一个三观比主角还正的技术人。我们下期再见!</em></p> <p style="text-align: left;white-space: normal;background-color: rgb(255, 255, 255);font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;font-size: 16px;color: rgba(0, 0, 0, 0.8);">欢迎关注!🤟<br></p> <p style="white-space: normal;background-color: rgb(255, 255, 255);font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;font-size: 16px;color: rgba(0, 0, 0, 0.8);text-align: center;"><img data-ratio="1" data-type="png" data-w="258" src="/upload/9f5e219fcf610bde551c66843a8ebc02.png" style="box-sizing: border-box !important;visibility: visible !important;width: 258px !important;"></p>
作者:微信小助手
<p style="margin-bottom: 10px;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;white-space: normal;color: rgb(62, 62, 62);font-size: 15px;background-color: rgb(255, 255, 255);line-height: normal;text-align: center;" data-mpa-powered-by="yiban.io"><span style="letter-spacing: 0.544px;font-size: 12px;color: rgb(136, 136, 136);"> </span><span style="font-size: 14px;letter-spacing: 0.544px;word-spacing: 2px;color: rgb(136, 136, 136);">点击蓝色“</span><span style="font-size: 14px;letter-spacing: 0.544px;word-spacing: 2px;color: rgb(0, 128, 255);">架构文摘</span><span style="font-size: 14px;letter-spacing: 0.544px;word-spacing: 2px;color: rgb(136, 136, 136);">”关注我哟</span></p> <p style="margin-bottom: 10px;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;white-space: normal;color: rgb(62, 62, 62);font-size: 15px;background-color: rgb(255, 255, 255);text-size-adjust: auto;word-spacing: 2px;text-align: center;"><span style="font-size: 14px;color: rgb(136, 136, 136);">加个“</span><span style="color: rgb(0, 128, 255);font-size: 14px;">星标</span><span style="font-size: 14px;color: rgb(136, 136, 136);">”,每天上午 09:25,干货推送!</span></p> <p style="font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;color: rgb(62, 62, 62);font-size: 14px;background-color: rgb(255, 255, 255);text-align: center;"><img data-backh="36" data-backw="578" data-ratio="0.0625" data-s="300,640" data-type="jpeg" data-w="640" width="100%" src="/upload/8c292e55ba5a23cb6ebc11f2a2c4fece.jpg" style="font-family: -apple-system-font, 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;visibility: visible !important;width: 677px !important;"></p> <section style="box-sizing: border-box;font-size: 16px;"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="padding-top: 10px;padding-right: 10px;padding-left: 10px;background-color: rgb(239, 239, 239);box-sizing: border-box;"> <span style="display: inline-block;width: 5%;line-height: 0.8;font-weight: bolder;font-size: 48px;box-sizing: border-box;" title="" opera-tn-ra-cell="_$.pages:0.layers:0.comps:0.txt1"> <section style="box-sizing: border-box;"> “ </section></span> <section style="display: inline-block;vertical-align: top;float: right;width: 90%;line-height: 1.5;font-size: 15px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><span style="letter-spacing: 1px;">富 Web 时代,应用变得越来越强大,与此同时也越来越复杂。集群部署、隔离环境、灰度发布以及动态扩容缺一不可,而容器化则成为中间的必要桥梁。</span></p> </section> <section style="clear: both;box-sizing: border-box;line-height: 0;"> <section style="line-height: 0;width: 0px;"> <svg viewbox="0 0 1 1" style="vertical-align:top;"></svg> </section> </section> </section> </section> </section> <section style="line-height: 1.75em;"> <br> </section> <p style="text-align: center;margin-left: 8px;margin-right: 8px;"><img class="rich_pages" data-ratio="0.5991983967935872" data-s="300,640" data-type="png" data-w="998" src="/upload/900b9389a1f51dc5eb066e3b3bb4893a.png" style=""></p> <section style="text-align: center;line-height: 1.75em;"> <span style="font-size: 14px;color: rgb(89, 89, 89);letter-spacing: 1px;"><em>图片来自 Pexels</em></span> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-mpa-template="t" mpa-from-tpl="t"> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">本文我们就来探索一下 Docker 的神秘世界,从零到一掌握 Docker 的基本原理与实践操作。别再守着前端那一亩三分地,是时候该开疆扩土了。</span></p> </section> </section> <section style="line-height: normal;"> <br> </section> <section style="box-sizing: border-box;font-size: 16px;"> <section style="border-bottom: 1px solid black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;border-bottom: 6px solid rgb(89, 89, 89);margin-bottom: -1px;border-top-color: rgb(89, 89, 89);border-right-color: rgb(89, 89, 89);border-left-color: rgb(89, 89, 89);font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">讲个故事</p> </section> </section> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <p style="line-height: normal;"><br></p> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-mpa-template="t" mpa-from-tpl="t"> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">为了更好的理解 Docker 是什么,我们先来讲个故事:</span></p> <section style="line-height: normal;"> <br> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">我需要盖一个房子,于是我搬石头、砍木头、画图纸、盖房子。一顿操作,终于把这个房子盖好了。</span> </section> <section mpa-from-tpl="t" mpa-is-content="t"> <p style="text-align: center;line-height: 1.75em;margin-left: 8px;margin-right: 8px;margin-bottom: 5px;"><img data-ratio="0.4462962962962963" data-type="png" data-w="1080" src="/upload/77865d977e11256ae95234c4adff66c1.png" style="box-sizing: border-box !important;word-wrap: break-word !important;width: 677px !important;visibility: visible !important;"></p> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">结果,住了一段时间,心血来潮想搬到海边去。这时候按以往的办法,我只能去海边,再次搬石头、砍木头、画图纸、盖房子。</span> </section> <section mpa-from-tpl="t" mpa-is-content="t"> <p style="text-align: center;line-height: 1.75em;margin-left: 8px;margin-right: 8px;margin-bottom: 5px;"><img data-ratio="0.6138888888888889" data-type="png" data-w="1080" src="/upload/47f051e06de4d4247531d35819461bdf.png" style="box-sizing: border-box !important;word-wrap: break-word !important;width: 677px !important;visibility: visible !important;"></p> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">烦恼之际,跑来一个魔法师教会我一种魔法。这种魔法可以把我盖好的房子复制一份,做成「镜像」,放在我的背包里。</span> </section> <section mpa-from-tpl="t" mpa-is-content="t"> <p style="text-align: center;line-height: 1.75em;margin-left: 8px;margin-right: 8px;margin-bottom: 5px;"><img data-ratio="0.562962962962963" data-type="png" data-w="1080" src="/upload/57cc9acc63d525790fa30b0b76881243.png" style="box-sizing: border-box !important;word-wrap: break-word !important;width: 677px !important;visibility: visible !important;"></p> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">等我到了海边,就用这个「镜像」,复制一套房子,拎包入住。</span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">是不是很神奇?对应到我们的项目中来,房子就是项目本身,镜像就是项目的复制,背包就是镜像仓库。</span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">如果要动态扩容,从仓库中取出项目镜像,随便复制就可以了。Build once,Run anywhere!</span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">不用再关注版本、兼容、部署等问题,彻底解决了「上线即崩,无休止构建」的尴尬。</span></p> </section> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <section style="line-height: normal;"> <br> </section> <section style="box-sizing: border-box;font-size: 16px;"> <section style="border-bottom: 1px solid black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;border-bottom: 6px solid rgb(89, 89, 89);margin-bottom: -1px;border-top-color: rgb(89, 89, 89);border-right-color: rgb(89, 89, 89);border-left-color: rgb(89, 89, 89);font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">虚拟机与容器</p> </section> </section> </section> <p style="line-height: normal;"><br></p> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-mpa-template="t" mpa-from-tpl="t"> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">开始之前,我们来做一些基础知识的储备:</span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">①虚拟机:虚拟化硬件</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">虚拟机 Virtual Machine 指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。在实体计算机中能够完成的工作在虚拟机中都能够实现。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">在计算机中创建虚拟机时,需要将实体机的部分硬盘和内存容量作为虚拟机的硬盘和内存容量。</span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">每个虚拟机都有独立的 CMOS、硬盘和操作系统,可以像使用实体机一样对虚拟机进行操作。在容器技术之前,业界的网红是虚拟机。</span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">虚拟机技术的代表,是 VMWare 和 OpenStack。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">②容器:将操作系统层虚拟化,是一个标准的软件单元</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span></p> <section style="line-height: normal;"> <br> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">其特点如下:</span> </section> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">随处运行:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">容器可以将代码与配置文件和相关依赖库进行打包,从而确保在任何环境下的运行都是一致的。</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">高资源利用率:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">容器提供进程级的隔离,因此可以更加精细地设置 CPU 和内存的使用率,进而更好地利用服务器的计算资源。</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">快速扩展:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">每个容器都可作为单独的进程予以运行,并且可以共享底层操作系统的系统资源,这样一来可以加快容器的启动和停止效率。</span></p></li> </ul> <section data-mpa-template="t" mpa-from-tpl="t"> <p style="line-height: normal;"><br></p> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">区别与联系:</span> </section> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">虚拟机虽然可以隔离出很多「子电脑」,但占用空间更大,启动更慢。虚拟机软件可能还要花钱,例如 VMWare。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">容器技术不需要虚拟出整个操作系统,只需要虚拟一个小规模的环境,类似「沙箱」。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">运行空间,虚拟机一般要几 GB 到 几十 GB 的空间,而容器只需要 MB 级甚至 KB 级。</span></p></li> </ul> <section data-mpa-template="t" mpa-from-tpl="t"> <p style="line-height: normal;"><br></p> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">我们来看一下对比数据:</span></p> <section mpa-from-tpl="t" mpa-is-content="t"> <section style="text-align: center;line-height: 1.75em;margin-left: 8px;margin-right: 8px;margin-bottom: 5px;"> <img data-ratio="0.4311797752808989" data-type="jpeg" data-w="712" src="/upload/415a0585271411734596db0a039a17d3.jpg" style="box-sizing: border-box !important;word-wrap: break-word !important;width: 677px !important;visibility: visible !important;"> </section> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">虚拟机属于虚拟化技术,而 Docker 这样的容器技术,属于轻量级的虚拟化。</span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">与虚拟机相比,容器更轻量且速度更快,因为它利用了 Linux 底层操作系统在隔离的环境中运行。</span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">虚拟机的 Hypervisor 创建了一个非常牢固的边界,以防止应用程序突破它,而容器的边界不那么强大。</span> </section> </section> </section> <p style="line-height: normal;"><br></p> <section style="box-sizing: border-box;font-size: 16px;"> <section style="border-bottom: 1px solid black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;border-bottom: 6px solid rgb(89, 89, 89);margin-bottom: -1px;border-top-color: rgb(89, 89, 89);border-right-color: rgb(89, 89, 89);border-left-color: rgb(89, 89, 89);font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">认识 Docker</p> </section> </section> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <p style="line-height: normal;"><br></p> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-mpa-template="t" mpa-from-tpl="t"> <section mpa-from-tpl="t" mpa-is-content="t"> <section style="text-align: center;line-height: 1.75em;margin-left: 8px;margin-right: 8px;margin-bottom: 5px;"> <img data-ratio="0.39166666666666666" data-type="png" data-w="1080" src="/upload/5e93a670b2346f6f8fc8130f99fb5359.png" style="box-sizing: border-box !important;word-wrap: break-word !important;width: 677px !important;visibility: visible !important;"> </section> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。</span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">Docker 技术的三大核心概念,分别是:</span> </section> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">镜像 Image</span></strong></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">容器 Container</span></strong></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">仓库 Repository</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span></p></li> </ul> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Docker 轻量级的原因是什么?</span> <span style="color: rgb(89, 89, 89);font-size: 15px;letter-spacing: 1px;">相信你也会有这样的疑惑:</span> <span style="color: rgb(89, 89, 89);font-size: 15px;letter-spacing: 1px;">为什么 Docker 启动快?</span> <span style="color: rgb(89, 89, 89);font-size: 15px;letter-spacing: 1px;">如何做到和宿主机共享内核?</span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">当我们请求 Docker 运行容器时,Docker 会在计算机上设置一个资源隔离的环境。</span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">然后将打包的应用程序和关联的文件复制到 Namespace 内的文件系统中,此时环境的配置就完成了。之后 Docker 会执行我们预先指定的命令,运行应用程序。</span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">镜像不包含任何动态数据,其内容在构建之后也不会被改变。</span> </section> </section> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <section style="line-height: normal;"> <br> </section> <section style="box-sizing: border-box;font-size: 16px;"> <section style="border-bottom: 1px solid black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;border-bottom: 6px solid rgb(89, 89, 89);margin-bottom: -1px;border-top-color: rgb(89, 89, 89);border-right-color: rgb(89, 89, 89);border-left-color: rgb(89, 89, 89);font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">核心概念</p> </section> </section> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">核心概念如下:</span> </section> </section> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Build,Ship and Run(搭建、运输、运行)。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Build once,Run anywhere(一次搭建,处处运行)。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Docker 本身并不是容器,它是创建容器的工具,是应用容器引擎。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Docker 三大核心概念,分别是:镜像 Image,容器 Container、仓库 Repository。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Docker 技术使用 Linux 内核和内核功能(例如 Cgroups 和 namespaces)来分隔进程,以便各进程相互独立运行。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">由于 Namespace 和 Cgroups 功能仅在 Linux 上可用,因此容器无法在其他操作系统上运行。那么 Docker 如何在 macOS 或 Windows 上运行?Docker 实际上使用了一个技巧,并在非 Linux 操作系统上安装 Linux 虚拟机,然后在虚拟机内运行容器。</span></p></li> <li><p><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">镜像是一个可执行包,其包含运行应用程序所需的代码、运行时、库、环境变量和配置文件,容器是镜像的运行时实例。</span></p></li> </ul> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-mpa-template="t" mpa-from-tpl="t"> <p style="line-height: normal;"><br></p> </section> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">更多关于 Docker 的原理,可以查看《</span><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Docker 工作原理及容器化简易指南</span><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">》,这里不再赘述:</span></p> <section style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: Helvetica Neue, Helvetica, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);background: rgb(40, 43, 46);padding: 0.5em;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;">http:<span style="font-size: inherit;line-height: inherit;color: rgb(128, 128, 128);word-wrap: inherit !important;word-break: inherit !important;">//dockone.io/article/8788</span><br></code></pre> </section> <p style="line-height: normal;"><br></p> </section> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <section style="box-sizing: border-box;font-size: 16px;"> <section style="border-bottom: 1px solid black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;border-bottom: 6px solid rgb(89, 89, 89);margin-bottom: -1px;border-top-color: rgb(89, 89, 89);border-right-color: rgb(89, 89, 89);border-left-color: rgb(89, 89, 89);font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">安装 Docker</p> </section> </section> </section> <section style="line-height: normal;"> <br> </section> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-mpa-template="t" mpa-from-tpl="t"> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">①命令行安装</span></strong> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">Homebrew 的 Cask 已经支持 Docker for Mac,因此可以很方便的使用 Homebrew Cask 来进行安装,执行如下命令:</span></p> <section style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: Helvetica Neue, Helvetica, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);background: rgb(40, 43, 46);padding: 0.5em;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">brew</span> cask install docker<br></code></pre> </section> <p style="line-height: normal;"><br></p> </section> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-mpa-template="t" mpa-from-tpl="t"> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">更多安装方式,请查看官方文档:</span></p> <section style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: Helvetica Neue, Helvetica, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);background: rgb(40, 43, 46);padding: 0.5em;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;">https:<span style="font-size: inherit;line-height: inherit;color: rgb(128, 128, 128);word-wrap: inherit !important;word-break: inherit !important;">//www.docker.com/get-started</span><br></code></pre> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">②查看版本</span></strong> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">命令如下:</span></p> <section style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: Helvetica Neue, Helvetica, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);background: rgb(40, 43, 46);padding: 0.5em;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">docker</span> -v<br></code></pre> </section> <p style="line-height: normal;"><br></p> </section> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-mpa-template="t" mpa-from-tpl="t"> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">③配置镜像加速</span></strong> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">设置 Docker Engine 写入配置:</span></p> <section style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: Helvetica Neue, Helvetica, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);background: rgb(40, 43, 46);padding: 0.5em;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;">{<br> <span style="font-size: inherit;line-height: inherit;color: rgb(165, 218, 45);word-wrap: inherit !important;word-break: inherit !important;">registry-mirrors</span>: [<br> <span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">http://hub-mirror.c.163.com/</span>,<br> <span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">https://registry.docker-cn.com</span><br> ],<br> <span style="font-size: inherit;line-height: inherit;color: rgb(165, 218, 45);word-wrap: inherit !important;word-break: inherit !important;">insecure-registries</span>:[],<br> <span style="font-size: inherit;line-height: inherit;color: rgb(165, 218, 45);word-wrap: inherit !important;word-break: inherit !important;">experimental</span>: <span style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">false</span>,<br> <span style="font-size: inherit;line-height: inherit;color: rgb(165, 218, 45);word-wrap: inherit !important;word-break: inherit !important;">debug</span>: <span style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">true</span><br>}<br></code></pre> </section> <section style="line-height: normal;"> <br> </section> </section> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-mpa-template="t" mpa-from-tpl="t"> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">④安装桌面端</span></strong> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span> </section> <section style="line-height: normal;"> <br> </section> <section mpa-from-tpl="t" mpa-is-content="t"> <section style="text-align: center;line-height: 1.75em;margin-left: 8px;margin-right: 8px;margin-bottom: 5px;"> <img data-ratio="0.5962962962962963" data-type="png" data-w="1080" src="/upload/d108701dbaac961e136192be3c3b54ed.png" style="box-sizing: border-box !important;word-wrap: break-word !important;width: 677px !important;visibility: visible !important;"> </section> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">桌面端操作非常简单,先去官网下载[1]。通过 Docker 桌面端,我们可以方便的操作:</span> </section> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">clone:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">克隆一个项目。</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">build:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">打包镜像。</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">run:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">运行实例。</span></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">share:</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">共享镜像。</span></p></li> </ul> <section data-mpa-template="t" mpa-from-tpl="t"> <p style="line-height: normal;"><br></p> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">好了,准备工作就绪,下面可以大展身手了!</span> </section> </section> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <p style="line-height: normal;"><br></p> <section style="box-sizing: border-box;font-size: 16px;"> <section style="border-bottom: 1px solid black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;" powered-by="xiumi.us"> <section style="display: inline-block;border-bottom: 6px solid rgb(89, 89, 89);margin-bottom: -1px;border-top-color: rgb(89, 89, 89);border-right-color: rgb(89, 89, 89);border-left-color: rgb(89, 89, 89);font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">快速开始</p> </section> </section> </section> <p style="line-height: normal;"><br></p> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-mpa-template="t" mpa-from-tpl="t"> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">安装完 Docker 之后,我们先打个实际项目的镜像,边学边用。</span> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">①首先需要大致了解一下我们将会用到的 11 个命令</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span></p> <section style="line-height: normal;"> <br> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">如下图:</span></p> <section mpa-from-tpl="t" mpa-is-content="t"> <p style="text-align: center;line-height: 1.75em;margin-left: 8px;margin-right: 8px;margin-bottom: 5px;"><img data-ratio="0.7032348804500703" data-type="jpeg" data-w="711" src="/upload/f728116c292f50db953261d726cd27be.jpg" style="box-sizing: border-box !important;word-wrap: break-word !important;width: 677px !important;visibility: visible !important;"></p> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">②新建项目</span></strong> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">为了快捷,我们直接使用 Vue 脚手架构建项目:</span></p> <section style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: Helvetica Neue, Helvetica, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);background: rgb(40, 43, 46);padding: 0.5em;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">vue</span> create docker-demo<br></code></pre> </section> <p style="line-height: normal;"><br></p> </section> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-mpa-template="t" mpa-from-tpl="t"> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">尝试启动一下:</span></p> <section style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: Helvetica Neue, Helvetica, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);background: rgb(40, 43, 46);padding: 0.5em;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">yarn</span> serve<br></code></pre> </section> <p style="line-height: normal;"><br></p> </section> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-mpa-template="t" mpa-from-tpl="t"> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">访问地址:http://localhost:8080/。项目就绪,我们接着为项目打包:</span></p> <section style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: Helvetica Neue, Helvetica, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);background: rgb(40, 43, 46);padding: 0.5em;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">yarn</span> build<br></code></pre> </section> <p style="line-height: normal;"><br></p> </section> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-mpa-template="t" mpa-from-tpl="t"> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">这时候,项目目录下的 Dist 就是我们要部署的静态资源了,我们继续下一步。</span> </section> <p style="line-height: normal;"><br></p> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">需要注意:前端项目一般分两类,一类直接 Nginx 静态部署,一类需要启动 Node 服务。本节我们只考虑第一种。关于 Node 服务,后文我会详细说明。</span> </section> <section style="line-height: normal;"> <br> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">③新建 Dockerfile</span></strong> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">命令如下:</span></p> <section style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: Helvetica Neue, Helvetica, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);background: rgb(40, 43, 46);padding: 0.5em;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">cd</span> docker-demo && touch Dockerfile<br></code></pre> </section> <p style="line-height: normal;"><br></p> </section> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-mpa-template="t" mpa-from-tpl="t"> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">此时的项目目录如下:</span></p> <section style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: Helvetica Neue, Helvetica, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);background: rgb(40, 43, 46);padding: 0.5em;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;">.<br>├── <span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">Dockerfile</span><br>├── <span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">README</span><span style="font-size: inherit;line-height: inherit;color: rgb(165, 218, 45);word-wrap: inherit !important;word-break: inherit !important;">.md</span><br>├── <span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">babel</span><span style="font-size: inherit;line-height: inherit;color: rgb(165, 218, 45);word-wrap: inherit !important;word-break: inherit !important;">.config</span><span style="font-size: inherit;line-height: inherit;color: rgb(165, 218, 45);word-wrap: inherit !important;word-break: inherit !important;">.js</span><br>├── <span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">dist</span><br>├── <span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">node_modules</span><br>├── <span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">package</span><span style="font-size: inherit;line-height: inherit;color: rgb(165, 218, 45);word-wrap: inherit !important;word-break: inherit !important;">.json</span><br>├── <span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">public</span><br>├── <span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">src</span><br>└── <span style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">yarn</span><span style="font-size: inherit;line-height: inherit;color: rgb(165, 218, 45);word-wrap: inherit !important;word-break: inherit !important;">.lock</span><br></code></pre> </section> <p style="line-height: normal;"><br></p> </section> </section> <section data-mpa-template="t" mpa-from-tpl="t"> <section data-mpa-template="t" mpa-from-tpl="t"> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">可以看到我们已经在 docker-demo 目录下成功创建了 Dockerfile 文件。</span> </section> <section style="line-height: normal;"> <br> </section> <section style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"> <strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">④准备 Nginx 镜像</span></strong> <span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">运行你的 Docker 桌面端,就会默认启动实例,我们在控制台拉取 Nginx 镜像:</span></p> <section style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: Helvetica Neue, Helvetica, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;"> <pr
作者:微信小助手
<section data-mpa-template="t" mpa-paragraph-type="ignored" style="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;letter-spacing: 0.544px;white-space: normal;text-size-adjust: auto;background-color: rgb(255, 255, 255);" data-mpa-powered-by="yiban.io"> <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;"><span data-mce-style="font-size: 10px" style="font-size: 13px;"><span style="color: rgb(136, 136, 136);">点击上方蓝色“</span></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;"><span style="color: rgb(136, 136, 136);">”,选择“设为星标”</span></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: center;font-size: 15px;color: rgb(64, 64, 64);line-height: 1.74;letter-spacing: 0.008em;outline-style: none;overflow-wrap: break-word;"><img data-ratio="0.6666666666666666" src="/upload/27e0dbd52f8dd0b3c31dceca7903993c.jpg" data-type="jpeg" data-w="960" style="width: 522px;height: 348px;"></p> <p data-lake-id="bfce4163fc935f17ecff696001dcbd90" style="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(178, 178, 178);font-size: 13px;" data-mce-style="font-size: 10px">来源 | cnblogs.com/youyoui/p/7851007.html</span></p> <section style="color: rgb(0, 0, 0);font-size: 16px;text-align: right;margin-left: 0px;margin-right: 0px;"> <span style="color: rgb(136, 136, 136);font-size: 10px;letter-spacing: 0.544px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;"><br></span> </section> </section> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="margin-top: -10px;padding-right: 10px;padding-left: 10px;white-space: normal;text-size-adjust: auto;font-size: 16px;color: black;line-height: 1.6;letter-spacing: 0px;word-break: break-word;text-align: left;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, 'PingFang SC', Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;"> <ul data-tool="mdnice编辑器" class="list-paddingleft-2" style="margin: 8px 0px;padding-left: 25px;"> <li style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;"> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <span style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;">准备工作</span> </section></li> <li style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;"> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <span style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;">一般分页查询</span> </section></li> <li style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;"> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <span style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;">使用子查询优化</span> </section></li> <li style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;"> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <span style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;">使用 id 限定优化</span> </section></li> <li style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;"> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <span style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;">使用临时表优化</span> </section></li> <li style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;"> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"> <span style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;">关于数据表的id说明</span> </section></li> </ul> <hr data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;height: 1px;border-style: solid none none;border-top-color: black;"> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);margin-left: 0px;margin-right: 0px;"> <span style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;">当需要从数据库查询的表有上万条记录的时候,一次性查询所有结果会变得很慢,特别是随着数据量的增加特别明显,这时需要使用分页查询。对于数据库分页查询,也有很多种方法和优化的点。下面简单说一下我知道的一些方法。</span> </section> <h1 data-tool="mdnice编辑器" style="margin: 30px 0px 15px;font-weight: bold;font-size: 24px;color: rgb(89, 89, 89);"><span style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;">准备工作</span></h1> <section style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: rgb(89, 89, 89);margin-left: 0px;margin-right: 0px;"> <