文章列表

Java中如何锁文件

作者:微信小助手

<section> <section style="margin: 10px 0%;text-align: center;"> <section style="display: inline-block;vertical-align: middle;width: 80%;padding-left: 10px;box-sizing: border-box;" data-width="80%"> <section style="box-sizing: border-box;"> <section style="color: #fa7f7f;box-sizing: border-box;"> <p style="text-shadow: rgb(251, 216, 216) 5px -3px 1px;box-sizing: border-box;font-size: 18px;"><span style="color: rgb(0, 82, 255);"><strong><span style="font-size: 14px;">点击左上角蓝字,关注“锅外的大佬”</span></strong></span><img src="/upload/3e8e6f059ad3a6eaf4bb1a86e5aba133.gif" data-type="gif" data-width="44%" style="font-size: 17px;vertical-align: middle;width: 25px;height: 29px;" data-ratio="1.1625" data-w="80"></p> </section> </section> </section> </section> </section> <section> <p style="text-align: center;margin-top: 5px;margin-bottom: 5px;line-height: normal;text-indent: 0em;"><strong style="color: rgb(217, 33, 66);font-family: Helvetica, Arial, sans-serif;font-size: 14px;letter-spacing: 0.544px;text-align: center;white-space: normal;">专注分享国外最新技术内容</strong></p> </section> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="font-size: 16px;padding: 10px;word-break: break-word;overflow-wrap: break-word;text-align: left;line-height: 1.75;color: rgb(89, 89, 89);font-family: Optima-Regular, Optima, PingFangTC-Light, PingFangSC-light, PingFangTC-light;letter-spacing: 2px;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;"> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 24px;margin-top: 20px;margin-right: 10px;"><span style="font-size: 18px;display: inline-block;padding-left: 10px;border-left: 5px solid rgb(222, 198, 251);color: rgb(89, 89, 89);">1. 概览</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">当读写文件时,需要确保有适当的文件锁定机制,来保证基于并发I/O应用程序的数据完整性。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;"><strong>「本教程中, 我们将介绍使用 Java NIO 库实现这一点的各种方法。」</strong></p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 24px;margin-top: 20px;margin-right: 10px;"><span style="font-size: 18px;display: inline-block;padding-left: 10px;border-left: 5px solid rgb(222, 198, 251);color: rgb(89, 89, 89);">2. 文件锁简介</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;"><strong>「一般来说,有两种锁」</strong>:</p> <ul data-tool="mdnice编辑器" style="list-style-type: circle;" class="list-paddingleft-2"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 独占锁——也称为写锁 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> 共享锁——也称为读锁 </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">简单地说,在写操作完成时,独占锁防止所有其他操作(包括读操作)。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">相反,共享锁允许多个进程同时读取。读锁的目的是防止另一个进程获取写锁。通常,处于一致状态的文件确实应该被任何进程读取。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">在下一节中,我们将看到Java如何处理这些类型的锁。</p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 24px;margin-top: 20px;margin-right: 10px;"><span style="font-size: 18px;display: inline-block;padding-left: 10px;border-left: 5px solid rgb(222, 198, 251);color: rgb(89, 89, 89);">3. Java中的文件锁</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">Java NIO库支持在操作系统级别锁定文件。<span style="background: rgb(246, 238, 255);">FileChannel</span> 中的<span style="background: rgb(246, 238, 255);">lock()</span> 和*tryLock()*方法就是为了这个而存在。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">我们可以通过 <span style="background: rgb(246, 238, 255);">FileInputStream</span>, <span style="background: rgb(246, 238, 255);">FileOutputStream</span>,<span style="background: rgb(246, 238, 255);">RandomAccessFile</span> 来获取<span style="background: rgb(246, 238, 255);">FileChannel</span>,三者均可通过 <span style="background: rgb(246, 238, 255);">getChannel()</span> 方法返回 <span style="background: rgb(246, 238, 255);">FileChannel</span>对象.</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">或者, 我们可以直接通过静态方法 <span style="background: rgb(246, 238, 255);">open</span> 来创建 <span style="background: rgb(246, 238, 255);">FileChannel</span> &nbsp;:</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> <li></li> <li></li> <li></li> </ul> <pre class="code-snippet__js" data-lang="java"><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">try (FileChannel channel = FileChannel.open(path, openOptions)) {</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> // write to the channel</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">}</span></code></pre> </section> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">接下来,我们将回顾在Java中获取独占锁和共享锁的不同方式。要了解有关文件通道的更多信息,请查看[Guide to Java FileChanne 教程。</p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 24px;margin-top: 20px;margin-right: 10px;"><span style="font-size: 18px;display: inline-block;padding-left: 10px;border-left: 5px solid rgb(222, 198, 251);color: rgb(89, 89, 89);">4. 独占锁</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">正如我们已经了解到的,在写入文件时,<strong>「我们可以使用独占锁」</strong>防止其他进程读取或写入文件。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">我们通过调用 <span style="background: rgb(246, 238, 255);">FileChannel</span> 类上的 <span style="background: rgb(246, 238, 255);">lock()</span> 或 <span style="background: rgb(246, 238, 255);">tryLock())</span> 来获得独占锁。我们还可以使用它们的重载方法:</p> <ul data-tool="mdnice编辑器" style="list-style-type: circle;" class="list-paddingleft-2"> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> <span style="background: rgb(246, 238, 255);">lock(long position, long size, boolean shared)</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;font-size: 14px;"> <span style="background: rgb(246, 238, 255);">tryLock(long position, long size, boolean shared)</span> </section></li> </ul> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">在这些情况下,<span style="background: rgb(246, 238, 255);">shared</span>参数必须设置为<span style="background: rgb(246, 238, 255);">false</span>。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">要获得独占锁,必须使用可写的<span style="background: rgb(246, 238, 255);">文件通道</span>。我们可以通过 <span style="background: rgb(246, 238, 255);">FileOutputStream</span> 或 <span style="background: rgb(246, 238, 255);">RandomAccessFile</span> 的 <span style="background: rgb(246, 238, 255);">getChannel()</span> 方法创建它。或者,如前所述,我们可以使用 <span style="background: rgb(246, 238, 255);">FileChannel</span> 类的静态方法:<span style="background: rgb(246, 238, 255);">open</span>。我们只需要将第二个参数设置为<span style="background: rgb(246, 238, 255);">StandardOpenOption.APPEND</span> :</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> <li></li> <li></li> <li></li> </ul> <pre class="code-snippet__js" data-lang="java"><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">try (FileChannel channel = FileChannel.open(path, StandardOpenOption.APPEND)) { </span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> // write to channel</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">}</span></code></pre> </section> <h3 data-tool="mdnice编辑器" style="margin-top: 40px;margin-bottom: 20px;color: black;font-weight: bold;text-align: center;"><span style="border-bottom: 2px solid #DEC6FB;color: #595959;">4.1. 使用 <span style="background: rgb(246, 238, 255);">FileOutputStream</span> 的独占锁</span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">从 <span style="background: rgb(246, 238, 255);">FileOutputStream</span> 创建的 <span style="background: rgb(246, 238, 255);">FileChannel</span> 是可写的。因此,我们可以获得一个独占锁:</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> <pre class="code-snippet__js" data-lang="java"><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">try (FileOutputStream fileOutputStream = new FileOutputStream("/tmp/testfile.txt");</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> FileChannel channel = fileOutputStream.getChannel();</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> FileLock lock = channel.lock()) { </span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> // write to the channel</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">}</span></code></pre> </section> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">在这里,<span style="background: rgb(246, 238, 255);">channel.lock()</span> 要么阻塞直到获得一个锁,要么抛出一个异常。例如,如果指定的区域已锁定,则会引发<span style="background: rgb(246, 238, 255);">OverlappingFileLockException</span>。有关可能的异常的完整列表,请参见Javadoc。我们还可以使用 <span style="background: rgb(246, 238, 255);">channel.tryLock()</span> 执行非阻塞锁。如果由于另一个程序持有一个重叠的锁而无法获取锁,则返回<span style="background: rgb(246, 238, 255);">null</span>。如果由于任何其他原因未能执行此操作,则会引发相应的异常。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 40px;margin-bottom: 20px;color: black;font-weight: bold;text-align: center;"><span style="border-bottom: 2px solid #DEC6FB;color: #595959;">4.2. 使用 <span style="background: rgb(246, 238, 255);">RandomAccessFile</span> 的独占锁</span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">使用 <span style="background: rgb(246, 238, 255);">RandomAccessFile</span>,我们需要设置 [constructor](https://docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html#RandomAccessFile(java.io.File, java.lang.String)) 方法的第二个参数。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">在这里,我们将使用读写权限打开文件:</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> <pre class="code-snippet__js" data-lang="java"><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">try (RandomAccessFile file = new RandomAccessFile("/tmp/testfile.txt", "rw");</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> FileChannel channel = file.getChannel();</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> FileLock lock = channel.lock()) {</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> // write to the channel</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">}</span></code></pre> </section> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">如果我们以只读模式打开文件,并尝试向其通道进行写入操作,将会抛出 <span style="background: rgb(246, 238, 255);">NonWritableChannelException</span> 异常。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 40px;margin-bottom: 20px;color: black;font-weight: bold;text-align: center;"><span style="border-bottom: 2px solid #DEC6FB;color: #595959;">4.3.独占锁依赖于可读的 <span style="background: rgb(246, 238, 255);">FileChannel</span></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">如前所述,独占锁需要一个可写通道。因此,我们无法通过从 <span style="background: rgb(246, 238, 255);">FileInputStream</span> 创建的 <span style="background: rgb(246, 238, 255);">FileChannel</span> 获得独占锁:</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> <pre class="code-snippet__js" data-lang="java"><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">Path path = Files.createTempFile("foo","txt");</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">Logger log = LoggerFactory.getLogger(this.getClass());</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">try (FileInputStream fis = new FileInputStream(path.toFile()); </span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> FileLock lock = fis.getChannel().lock()) {</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> // unreachable code</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">} catch (NonWritableChannelException e) {</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> // handle exception</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">}</span></code></pre> </section> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">在上面的例子中,<span style="background: rgb(246, 238, 255);">lock()</span> 方法将抛出一个 <span style="background: rgb(246, 238, 255);">nonwriteablechannelexception</span> 。实际上,这是因为我们正在对一个创建只读通道的 <span style="background: rgb(246, 238, 255);">FileInputStream</span> 调用 <span style="background: rgb(246, 238, 255);">getChannel</span>。这个例子只是为了证明我们不能写到一个不可写的通道。事实上,我们不会捕捉并重新抛出异常。</p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 24px;margin-top: 20px;margin-right: 10px;"><span style="font-size: 18px;display: inline-block;padding-left: 10px;border-left: 5px solid rgb(222, 198, 251);color: rgb(89, 89, 89);">5. &nbsp;共享锁</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">记住,共享锁也称为<span style="background: rgb(246, 238, 255);">读</span> 锁。因此,要获得读锁,我们必须使用可读的<span style="background: rgb(246, 238, 255);">文件通道</span>。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">这样的 <span style="background: rgb(246, 238, 255);">FileChannel</span> 可以通过调用 <span style="background: rgb(246, 238, 255);">FileInputStream</span> 或 <span style="background: rgb(246, 238, 255);">RandomAccessFile</span> 上的 <span style="background: rgb(246, 238, 255);">getChannel()</span> 方法获得。同样,另一个选项是使用 <span style="background: rgb(246, 238, 255);">FileChannel</span> 类的静态 <span style="background: rgb(246, 238, 255);">open</span> 方法。在这种情况下,我们将第二个参数设置为 <span style="background: rgb(246, 238, 255);">StandardOpenOption.READ</span> 。</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> <li></li> <li></li> <li></li> <li></li> </ul> <pre class="code-snippet__js" data-lang="java"><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">try (FileChannel channel = FileChannel.open(path, StandardOpenOption.READ);</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> FileLock lock = channel.lock(0, Long.MAX_VALUE, true)) {</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> // read from the channel</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">}</span></code></pre> </section> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">这里要注意的一点是,我们选择通过调用 <span style="background: rgb(246, 238, 255);">lock(0, Long.MAX_VALUE, true)</span> 来锁定整个文件。通过将前两个参数更改为不同的值,我们还可以只锁定文件的特定区域。对于共享锁,第三个参数必须设置为<span style="background: rgb(246, 238, 255);">true</span>。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">为了简单起见,我们将在下面的所有示例中锁定整个文件,但请记住,我们始终可以锁定文件的特定区域。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 40px;margin-bottom: 20px;color: black;font-weight: bold;text-align: center;"><span style="border-bottom: 2px solid #DEC6FB;color: #595959;">5.1. 使用 <span style="background: rgb(246, 238, 255);">FileInputStream</span> 中的共享锁</span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">从 <span style="background: rgb(246, 238, 255);">FileInputStream</span> 获得的 <span style="background: rgb(246, 238, 255);">FileChannel</span> 是可读的。因此,我们可以获得一个共享锁:</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> <pre class="code-snippet__js" data-lang="java"><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">try (FileInputStream fileInputStream = new FileInputStream("/tmp/testfile.txt");</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> FileChannel channel = fileInputStream.getChannel();</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> FileLock lock = channel.lock(0, Long.MAX_VALUE, true)) {</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> // read from the channel</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">}</span></code></pre> </section> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">在上面的代码片段中,将成功调用通道上的 <span style="background: rgb(246, 238, 255);">lock()</span> 。这是因为共享锁只要求通道是可读的就行。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 40px;margin-bottom: 20px;color: black;font-weight: bold;text-align: center;"><span style="border-bottom: 2px solid #DEC6FB;color: #595959;">5.2. 使用 <span style="background: rgb(246, 238, 255);">RandomAccessFile</span>中的共享锁</span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">这次,我们只需要使用 ''读" 权限打开文件即可:</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> <pre class="code-snippet__js" data-lang="java"><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">try (RandomAccessFile file = new RandomAccessFile("/tmp/testfile.txt", "r"); </span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> FileChannel channel = file.getChannel();</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> FileLock lock = channel.lock(0, Long.MAX_VALUE, true)) {</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> // read from the channel</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">}</span></code></pre> </section> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">在本例中,我们创建了一个具有读取权限的<span style="background: rgb(246, 238, 255);">RandomAccessFile</span>对象,然后从中创建一个可读通道,从而创建一个共享锁。</p> <h3 data-tool="mdnice编辑器" style="margin-top: 40px;margin-bottom: 20px;color: black;font-weight: bold;text-align: center;"><span style="border-bottom: 2px solid #DEC6FB;color: #595959;">5.3. 共享锁依赖于可读的 <span style="background: rgb(246, 238, 255);">FileChannel</span></span></h3> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">因此,我们无法通过从 <span style="background: rgb(246, 238, 255);">FileOutputStream</span> 创建的 <span style="background: rgb(246, 238, 255);">FileChannel</span> 获取共享锁:</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> <pre class="code-snippet__js" data-lang="java"><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">Path path = Files.createTempFile("foo","txt");</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">try (FileOutputStream fis = new FileOutputStream(path.toFile()); </span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> FileLock lock = fis.getChannel().lock(0, Long.MAX_VALUE, true)) {</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> // unreachable code</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">} catch (NonWritableChannelException e) { </span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;"> // handle exception</span></code><code style=" border-radius: 0px;white-space: pre;display: flex; font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; "><span class="code-snippet_outer" style="line-height: 26px;">}</span></code></pre> </section> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">在本例中,调用 <span style="background: rgb(246, 238, 255);">lock()</span> 尝试获取从 <span style="background: rgb(246, 238, 255);">FileOutputStream</span> 创建的通道上的共享锁。这样的通道是只写的。它不能满足通道必须可读的需要。这将触发一个<span style="background: rgb(246, 238, 255);">NonWritableChannelException</span>。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">同样,这段代码只是为了证明我们不能从一个不可读的通道中读取。</p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 24px;margin-top: 20px;margin-right: 10px;"><span style="font-size: 18px;display: inline-block;padding-left: 10px;border-left: 5px solid rgb(222, 198, 251);color: rgb(89, 89, 89);">6. 思考</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">实际上,使用文件锁是困难的;锁定机制是不可移植的。我们需要考虑到这一点来设计锁定逻辑。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">在POSIX系统中,锁是建议性的。读取或写入给定文件的不同进程必须就锁定协议达成一致。这将确保文件的完整性。操作系统本身不会强制任何锁定。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">在Windows上,除非允许共享,否则锁将是独占的。讨论操作系统特定机制的优点或缺点超出了本文的讨论范围。然而,在实现锁定机制时,了解这些细微差别很重要。</p> <h2 data-tool="mdnice编辑器" style="font-weight: bold;color: black;font-size: 24px;margin-top: 20px;margin-right: 10px;"><span style="font-size: 18px;display: inline-block;padding-left: 10px;border-left: 5px solid rgb(222, 198, 251);color: rgb(89, 89, 89);">7. 总结</span></h2> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">在本教程中,我们回顾了在Java中获取文件锁的几种不同选项。</p> <p data-tool="mdnice编辑器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;margin-top: 10px;margin-bottom: 10px;font-size: 14px;word-spacing: 2px;">首先,我们首先了解两种主要的锁定机制,以及Java NIO库如何促进锁定文件。然后,我们浏览了一系列简单的示例,这些示例显示我们可以在应用程序中获得独占和共享锁。我们还研究了使用文件锁时可能遇到的典型异常类型。<span style="text-align: center;color: rgb(51, 51, 51);font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 17px;">&nbsp;</span></p> </section> <section style="font-size: 16px;color: black;padding: 10px;line-height: 1.6;letter-spacing: 0px;overflow-wrap: break-word;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;word-break: break-all;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;"> <section data-support="96编辑器" data-style-id="24435"> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;"> <section style="display:inline-block;background-color:#fefefe;width: 50%;" data-width="50%"> <p style="padding-top: 5px;padding-bottom: 5px;line-height: 26px;margin-right: auto;margin-left: auto;"><img data-ratio="0.204" src="/upload/6081f60ca484a01a5a44b04addbb1259.gif" data-type="gif" data-w="500" style="margin-right: auto;margin-left: auto;width: 100%;display: block;"></p> </section> <section style="margin-top: -20px;border-radius: 8px;border-style: solid;border-width: 2px;border-color: rgb(160, 201, 228);padding: 30px 15px;box-sizing: border-box;"> <p style="padding-top: 5px;padding-bottom: 5px;line-height: 26px;letter-spacing: 2px;text-align: left;"><span style="font-size: 14px;color: rgb(158, 162, 250);">●<a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzIzNzYxNDYzNw==&amp;mid=2247484293&amp;idx=1&amp;sn=f688a0c8963ad1fa4f253c03d64633e7&amp;chksm=e8c4a0c7dfb329d16a9c53ae8e608ab3b1b2cd04ffdae5e944b3ab8132e33aa0e0a3dabd02d9&amp;scene=21#wechat_redirect" data-itemshowtype="11" tab="innerlink" data-linktype="2">ZooKeeper 入门看这篇就够了</a></span><span style="color: rgb(49, 178, 230);font-size: 14px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;widows: 1;"></span></p> <p style="padding-top: 5px;padding-bottom: 5px;line-height: 26px;letter-spacing: 2px;text-align: left;"><span style="font-size: 14px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;widows: 1;color: rgb(158, 162, 250);">●<a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzIzNzYxNDYzNw==&amp;mid=2247484287&amp;idx=1&amp;sn=1da5703ab3ab3f0d8bdd16bbd47ddce1&amp;chksm=e8c4a03ddfb3292bd9fd478ea33f29bf8354f0f6d9971b189e977ddde4ad05edb87fac4f9541&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">不管你年底换不换工作,了解下单例模式</a></span><span style="font-size: 14px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;widows: 1;color: rgb(49, 178, 230);"></span></p> <p style="padding-top: 5px;padding-bottom: 5px;line-height: 26px;letter-spacing: 2px;text-align: left;"><span style="font-size: 14px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;widows: 1;color: rgb(158, 162, 250);">●<a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzIzNzYxNDYzNw==&amp;mid=2247484279&amp;idx=1&amp;sn=dc1f3c8aaaab207a8593cf9875feba03&amp;chksm=e8c4a035dfb329231013d44e314b11f30998ae510389e2e6078d9e957a84ec96f47d90b92f7c&amp;scene=21#wechat_redirect" data-itemshowtype="11" tab="innerlink" data-linktype="2">Spring Boot 代码简化利器 lombok</a></span><span style="font-size: 14px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;widows: 1;color: rgb(49, 178, 230);"></span></p> </section> </section> </section> <p style="text-align: center;"><span style="color: rgb(0, 82, 255);"><strong style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 14px;text-align: center;white-space: normal;"><span style="font-family: Roboto, Oxygen, Ubuntu, Cantarell, PingFangSC-light, PingFangTC-light, &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, sans-serif;text-align: start;background-color: rgb(255, 255, 255);">右上角按钮分享给更多人哦~</span></strong></span><span style="color: rgb(0, 82, 255);"><strong style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 14px;text-align: center;white-space: normal;"><span style="font-family: Roboto, Oxygen, Ubuntu, Cantarell, PingFangSC-light, PingFangTC-light, &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, sans-serif;text-align: start;background-color: rgb(255, 255, 255);"><img src="/upload/bdebeb96d99dba4b9471ab46678229a3.null" data-ratio="1" data-w="20" style="display: inline-block;width: 20px;vertical-align: text-bottom;"><img src="/upload/bdebeb96d99dba4b9471ab46678229a3.null" data-ratio="1" data-w="20" style="display: inline-block;width: 20px;vertical-align: text-bottom;"></span></strong></span></p> <p style="text-align: center;"><img class="rich_pages" data-backh="536" data-backw="536" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/6tgwFZrjh8GgpNYZs1Ws7ILGYwwH7icyWXre2ic1lWWRsj4HYF6JcWLuaxfJwoI9VLHgdica3KnGs55qYGaBOLJKg/0?wx_fmt=png" data-copyright="0" data-ratio="1" data-s="300,640" src="/upload/96171a9cdb60d0b54d1dd9d212b93ae0.png" data-type="png" data-w="600" style="width: 100%;height: auto;"></p> <section data-support="96编辑器" data-style-id="23718"> <section style="margin-top: 10px;margin-bottom: 10px;text-align: right;"> <section style="display:inline-block;"> <section style="display: flex;justify-content:center;align-items: center;"> <section> <p><span style="letter-spacing: 2px;font-size: 14px;"><strong>来都来了,点个在看再走吧</strong></span><span style="font-size: 14px;letter-spacing:2px;"><strong>~~~</strong></span></p> <section style="width: 40px;height: 1px;background-color: rgb(98, 185, 221);"> <br> </section> <section style="margin-left: 20px;margin-top: 2px;width: 40px;height: 1px;background-color: rgb(98, 185, 221);"> <br> </section> </section> <section style="width: 30px;"> <img src="/upload/c1d500ea070276c9924fb89a506aafcc.gif" style="z-index: -1;cursor: pointer;vertical-align: middle;width: auto;" data-type="gif" data-ratio="1.1346153846153846" data-w="52"> </section> </section> </section> </section> </section> </section>

垃圾回收-实战篇

作者:微信小助手

<p style="margin-top: 1.5em;margin-bottom: 1.5em;max-width: 100%;min-height: 1em;caret-color: rgb(62, 62, 62);color: inherit;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;white-space: normal;text-size-adjust: auto;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><a href="https://mp.weixin.qq.com/s?__biz=MzI5MTU1MzM3MQ==&amp;mid=2247483910&amp;idx=1&amp;sn=28134eb9eea657da0d54337d69230c29&amp;scene=21#wechat_redirect" data-linktype="2" style="color: rgb(30, 107, 184);cursor: pointer;max-width: 100%;line-height: inherit;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">上文</span></a><span style="font-size: 15px;">&nbsp;GC 理论颇受大家好评,学习了之后,相信大家对 GC 的工作原理有了比较深刻的认识,这一篇我们继续趁热打铁,来学习下 GC 的实战内容,主要包括以下几点</span></p> <ul class="list-paddingleft-2" style=""> <li><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: inherit;line-height: inherit;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">JVM 参数简介</span></p></li> <li><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: inherit;line-height: inherit;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">发生 OOM 的主要几种场景及相应解决方案</span></p></li> <li><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: inherit;line-height: inherit;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">OOM 问题排查的一些常用工具</span></p></li> <li><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: inherit;line-height: inherit;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">GC 日志格式怎么看</span></p></li> <li><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: inherit;line-height: inherit;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">jstat 与可视化 APM 工具构建</span></p></li> <li><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: inherit;line-height: inherit;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">再谈 JVM 参数设置</span></p></li> </ul> <h2 style="margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.4em;max-width: 100%;caret-color: rgb(62, 62, 62);color: inherit;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;white-space: normal;text-size-adjust: auto;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: inherit;line-height: inherit;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">JVM 参数简介</span></h2> <p style="margin-top: 1.5em;margin-bottom: 1.5em;max-width: 100%;min-height: 1em;caret-color: rgb(62, 62, 62);color: inherit;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;white-space: normal;text-size-adjust: auto;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">在开始实践之前我们有必要先简单了解一下 JVM 参数配置,因为本文之后的实验中提到的 JVM 中的栈,堆大小,使用的垃圾收集器等都需要通过 JVM 参数来设置</span></p> <p style="margin-top: 1.5em;margin-bottom: 1.5em;max-width: 100%;min-height: 1em;caret-color: rgb(62, 62, 62);color: inherit;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;white-space: normal;text-size-adjust: auto;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">先来看下如何运行一个 Java 程序</span></p> <pre style="max-width: 100%;caret-color: rgb(62, 62, 62);color: inherit;font-size: inherit;text-size-adjust: auto;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;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);background-color: 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;"><span style="max-width: 100%;line-height: inherit;color: rgb(248, 35, 117);box-sizing: border-box !important;overflow-wrap: inherit !important;word-break: inherit !important;">public</span>&nbsp;<span style="max-width: 100%;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="max-width: 100%;line-height: inherit;color: rgb(248, 35, 117);">class</span>&nbsp;<span style="max-width: 100%;line-height: inherit;color: rgb(165, 218, 45);">Test</span>&nbsp;</span>{<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="max-width: 100%;line-height: inherit;color: rgb(248, 35, 117);box-sizing: border-box !important;overflow-wrap: inherit !important;word-break: inherit !important;"><span style="max-width: 100%;line-height: inherit;">public</span>&nbsp;<span style="max-width: 100%;line-height: inherit;">static</span>&nbsp;&nbsp;<span style="max-width: 100%;line-height: inherit;">void</span>&nbsp;<span style="max-width: 100%;line-height: inherit;color: rgb(165, 218, 45);">main</span><span style="max-width: 100%;line-height: inherit;color: rgb(255, 152, 35);">(String[]&nbsp;args)</span>&nbsp;</span>{<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<span style="max-width: 100%;line-height: inherit;color: rgb(238, 220, 112);box-sizing: border-box !important;overflow-wrap: inherit !important;word-break: inherit !important;">"test"</span>);<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">&nbsp;&nbsp;&nbsp;&nbsp;}<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">}<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></code></pre> <ol class="list-paddingleft-2" style=""> <li><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">首先我们通过&nbsp;<strong style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;">javac Test.java</strong>&nbsp;将其转成字节码</span></p></li> <li><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">其次我们往往会输入&nbsp;<strong style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;">java Test</strong>&nbsp;这样的命令来启动 JVM 进程来执行此程序,其实我们在启动 JVM 进程的时候,可以指定相应的 JVM 的参数,如下蓝色部分<br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></span></p> <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.12643678160919541" data-type="png" data-w="1566" title="" src="/upload/a0c3515c95c213ff04459fee78e425d2.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: 677px !important;visibility: visible !important;"> </figure></li> </ol> <p style="margin-top: 1.5em;margin-bottom: 1.5em;max-width: 100%;min-height: 1em;caret-color: rgb(62, 62, 62);color: inherit;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;white-space: normal;text-size-adjust: auto;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">指定这些 JVM 参数我们就可以指定启动 JVM 进程以哪种模式(server 或 client),运行时分配的堆大小,栈大小,用什么垃圾收集器等等,JVM 参数主要分以下三类</span></p> <p style="margin-top: 1.5em;margin-bottom: 1.5em;max-width: 100%;min-height: 1em;caret-color: rgb(62, 62, 62);color: inherit;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;white-space: normal;text-size-adjust: auto;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">1、 标准参数(-),所有的 JVM 实现都必须实现这些参数的功能,而且向后兼容;例如&nbsp;<strong style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;">-verbose:gc</strong>(输出每次GC的相关情况)</span></p> <p style="margin-top: 1.5em;margin-bottom: 1.5em;max-width: 100%;min-height: 1em;caret-color: rgb(62, 62, 62);color: inherit;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;white-space: normal;text-size-adjust: auto;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">2、 非标准参数(-X),默认 JVM 实现这些参数的功能,但是并不保证所有 JVM 实现都满足,且不保证向后兼容,栈,堆大小的设置都是通过这个参数来配置的,用得最多的如下</span></p> <table> <thead style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <th style="padding: 0.5em 1em;word-break: break-all;border-top-width: 1px;border-color: rgb(204, 204, 204);background-color: rgb(240, 240, 240);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;text-align: left;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="154"><span style="font-size: 15px;">参数示例</span></th> <th style="padding: 0.5em 1em;word-break: break-all;border-top-width: 1px;border-color: rgb(204, 204, 204);background-color: rgb(240, 240, 240);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;text-align: left;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="284"><span style="font-size: 15px;">表示意义</span></th> </tr> </thead> <tbody style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 0px;border-style: initial;border-color: initial;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="61"><span style="font-size: 15px;">-Xms512m</span></td> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="300"><span style="font-size: 15px;">JVM 启动时设置的初始堆大小为 512M</span></td> </tr> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="61"><span style="font-size: 15px;">-Xmx512m</span></td> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="300"><span style="font-size: 15px;">JVM 可分配的最大堆大小为 512M</span></td> </tr> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="61"><span style="font-size: 15px;">-Xmn200m</span></td> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="300"><span style="font-size: 15px;">设置的年轻代大小为 200M</span></td> </tr> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="61"><span style="font-size: 15px;">-Xss128k</span></td> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="300"><span style="font-size: 15px;">设置每个线程的栈大小为 128k</span></td> </tr> </tbody> </table> <p style="margin-top: 1.5em;margin-bottom: 1.5em;max-width: 100%;min-height: 1em;caret-color: rgb(62, 62, 62);color: inherit;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;white-space: normal;text-size-adjust: auto;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">3、非Stable参数(-XX),此类参数各个 jvm 实现会有所不同,将来可能会随时取消,需要慎重使用, -XX:-option 代表关闭 option 参数,-XX:+option 代表要关闭 option 参数,例如要启用串行 GC,对应的 JVM 参数即为 -XX:+UseSerialGC。非 Stable 参数主要有三大类</span></p> <ul class="list-paddingleft-2" style=""> <li><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: inherit;line-height: inherit;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">行为参数(Behavioral Options):用于改变 JVM 的一些基础行为,如启用串行/并行 GC</span></p></li> </ul> <table> <thead style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <th style="padding: 0.5em 1em;word-break: break-all;border-top-width: 1px;border-color: rgb(204, 204, 204);background-color: rgb(240, 240, 240);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;text-align: left;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="46"><span style="font-size: 15px;">参数示例</span></th> <th style="padding: 0.5em 1em;word-break: break-all;border-top-width: 1px;border-color: rgb(204, 204, 204);background-color: rgb(240, 240, 240);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;text-align: left;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="347"><span style="font-size: 15px;">表示意义</span></th> </tr> </thead> <tbody style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 0px;border-style: initial;border-color: initial;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="46"><span style="font-size: 15px;">-XX:-DisableExplicitGC</span></td> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="326"><span style="font-size: 15px;">禁止调用System.gc();但jvm的gc仍然有效</span></td> </tr> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="221"><span style="font-size: 15px;">-XX:-UseConcMarkSweepGC</span></td> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="341"><span style="font-size: 15px;">对老生代采用并发标记交换算法进行GC</span></td> </tr> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="46"><span style="font-size: 15px;">-XX:-UseParallelGC</span></td> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="341"><span style="font-size: 15px;">启用并行GC</span></td> </tr> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="46"><span style="font-size: 15px;">-XX:-UseParallelOldGC</span></td> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="341"><span style="font-size: 15px;">对Full GC启用并行,当-XX:-UseParallelGC启用时该项自动启用</span></td> </tr> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="46"><span style="font-size: 15px;">-XX:-UseSerialGC</span></td> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="340"><span style="font-size: 15px;">启用串行GC</span></td> </tr> </tbody> </table> <ul class="list-paddingleft-2" style=""> <li><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: inherit;line-height: inherit;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">性能调优(Performance Tuning):用于 jvm 的性能调优,如设置新老生代内存容量比例</span></p></li> </ul> <table> <thead style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <th style="padding: 0.5em 1em;word-break: break-all;border-top-width: 1px;border-color: rgb(204, 204, 204);background-color: rgb(240, 240, 240);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;text-align: left;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="279"><span style="font-size: 15px;">参数示例</span></th> <th style="padding: 0.5em 1em;word-break: break-all;border-top-width: 1px;border-color: rgb(204, 204, 204);background-color: rgb(240, 240, 240);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;text-align: left;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="277"><span style="font-size: 15px;">表示意义</span></th> </tr> </thead> <tbody style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 0px;border-style: initial;border-color: initial;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="29"><span style="font-size: 15px;">-XX:MaxHeapFreeRatio=70</span></td> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="268"><span style="font-size: 15px;">GC后java堆中空闲量占的最大比例</span></td> </tr> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="29"><span style="font-size: 15px;">-XX:NewRatio=2</span></td> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="268"><span style="font-size: 15px;">新生代内存容量与老生代内存容量的比例</span></td> </tr> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="29"><span style="font-size: 15px;">-XX:NewSize=2.125m</span></td> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="268"><span style="font-size: 15px;">新生代对象生成时占用内存的默认值</span></td> </tr> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="29"><span style="font-size: 15px;">-XX:ReservedCodeCacheSize=32m</span></td> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="268"><span style="font-size: 15px;">保留代码占用的内存容量</span></td> </tr> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="29"><span style="font-size: 15px;">-XX:ThreadStackSize=512</span></td> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="268"><span style="font-size: 15px;">设置线程栈大小,若为0则使用系统默认值</span></td> </tr> </tbody> </table> <ul class="list-paddingleft-2" style=""> <li><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: inherit;line-height: inherit;font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;">调试参数(Debugging Options):一般用于打开跟踪、打印、输出等 JVM 参数,用于显示 JVM 更加详细的信息</span></p></li> </ul> <table> <thead style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <th style="padding: 0.5em 1em;word-break: break-all;border-top-width: 1px;border-color: rgb(204, 204, 204);background-color: rgb(240, 240, 240);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;text-align: left;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="346"><span style="font-size: 15px;">参数示例</span></th> <th style="padding: 0.5em 1em;word-break: break-all;border-top-width: 1px;border-color: rgb(204, 204, 204);background-color: rgb(240, 240, 240);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;text-align: left;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="210"><span style="font-size: 15px;">表示意义</span></th> </tr> </thead> <tbody style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 0px;border-style: initial;border-color: initial;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="83"><span style="font-size: 15px;">-XX:HeapDumpPath=./java_pid</span> <pid style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <span style="font-size: 15px;">.hprof</span> </pid></td> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="200"><span style="font-size: 15px;">指定导出堆信息时的路径或文件名</span></td> </tr> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="83"><span style="font-size: 15px;">-XX:-HeapDumpOnOutOfMemoryError</span></td> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="200"><span style="font-size: 15px;">当首次遭遇OOM时导出此时堆中相关信息</span></td> </tr> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="83"><span style="font-size: 15px;">-XX:-PrintGC</span></td> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="200"><span style="font-size: 15px;">每次GC时打印相关信息</span></td> </tr> <tr style="max-width: 100%;font-size: inherit;color: inherit;line-height: inherit;border-width: 1px 0px 0px;border-top-style: solid;border-top-color: rgb(204, 204, 204);background-color: white;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="83"><span style="font-size: 15px;">-XX:-PrintGC Details</span></td> <td style="padding: 0.5em 1em;word-break: break-all;border-color: rgb(204, 204, 204);max-width: 100%;color: inherit;line-height: inherit;font-size: 1em;overflow-wrap: break-word !important;box-sizing: border-box !important;" width="200"><span style="font-size: 15px;">每次GC时打印详细信息</span></td> </tr> </tbody> </table> <p style="margin-top: 1.5em;margin-bottom: 1.5em;max-width: 100%;min-height: 1em;caret-color: rgb(62, 62, 62);color: inherit;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;white-space: normal;text-size-adjust: auto;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><em style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(0, 128, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;">画外音:以上只是列出了比较常用的 JVM 参数,更多的 JVM 参数介绍请查看文末的参考资料</span></em></span></p> <p style="margin-top: 1.5em;margin-bottom: 1.5em;max-width: 100%;min-height: 1em;caret-color: rgb(62, 62, 62);color: inherit;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;white-space: normal;text-size-adjust: auto;line-height: inherit;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;">明白了 JVM 参数是干啥用的,接下来我们进入实战演练,下文中所有程序运行时对应的 JVM 参数都以 VM Args 的形式写在开头的注释里,读者如果在执行程序时记得要把这些 JVM 参数给带上哦</span></p> <h2 style="margin-top: 1.5em;margin-bottom: 1.5em;font-weight: bold;font-size: 1.4em;max-width: 100%;caret-color: rgb(62, 62, 62);color: inherit;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quo

手把手教你搭建 ELK 实时日志分析平台

作者:微信小助手

<section> <section style="margin: 10px 0%;text-align: center;"> <section style="display: inline-block;vertical-align: middle;width: 80%;padding-left: 10px;box-sizing: border-box;" data-width="80%"> <section style="box-sizing: border-box;"> <section style="color: #fa7f7f;box-sizing: border-box;"> <p style="text-shadow: rgb(251, 216, 216) 5px -3px 1px;box-sizing: border-box;font-size: 18px;"><span style="color: rgb(0, 82, 255);"><strong><span style="font-size: 14px;">点击左上角蓝字,关注“锅外的大佬”</span></strong></span><img src="/upload/3e8e6f059ad3a6eaf4bb1a86e5aba133.gif" data-type="gif" data-width="44%" style="font-size: 17px;vertical-align: middle;width: 25px;height: 29px;" data-ratio="1.1625" data-w="80"></p> </section> </section> </section> </section> </section> <section> <p style="text-align: center;margin-top: 5px;margin-bottom: 5px;line-height: normal;text-indent: 0em;"><strong style="color: rgb(217, 33, 66);font-family: Helvetica, Arial, sans-serif;font-size: 14px;letter-spacing: 0.544px;text-align: center;white-space: normal;">专注分享国外最新技术内容</strong></p> </section> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">本篇文章主要是手把手教你搭建 ELK 实时日志分析平台,那么,ELK 到底是什么呢?</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">ELK 是三个开源项目的首字母缩写,这三个项目分别是:Elasticsearch、Logstash 和 Kibana。</p> <ul data-tool="mdnice编辑器" class="list-paddingleft-2" style=""> <li> <section style="margin-top: 10px;margin-bottom: 10px;line-height: 26px;color: rgb(1, 1, 1);"> Elasticsearch 是一个 <strong style="color: rgb(53, 179, 120);">搜索和分析引擎</strong>。 </section></li> <li> <section style="margin-top: 10px;margin-bottom: 10px;line-height: 26px;color: rgb(1, 1, 1);"> Logstash 是 <strong style="color: rgb(53, 179, 120);">服务器端数据处理管道</strong>,能够同时从多个来源采集数据,转换数据,然后将数据发送到诸如 Elasticsearch 等存储库中。 </section></li> <li> <section style="margin-top: 10px;margin-bottom: 10px;line-height: 26px;color: rgb(1, 1, 1);"> Kibana 则可以让用户在 Elasticsearch 中 <strong style="color: rgb(53, 179, 120);">使用图形和图表对数据进行可视化</strong>。 </section></li> </ul> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;color: rgb(89, 89, 89);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 15px;letter-spacing: 0.75px;text-align: left;white-space: normal;"> <img data-ratio="0.5405405405405406" src="/upload/735a68a0b64801024a07bb4954acd91c.png" data-type="png" data-w="555" style="margin-right: auto;margin-left: auto;display: block;width: 558px;"> <figcaption style="margin-top: 5px;text-align: center;color: rgb(136, 136, 136);font-size: 14px;"> ELK Stack </figcaption> </figure> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">Elasticsearch 的核心是搜索引擎,所以用户开始将其用于日志用例,并希望能够轻松地对日志进行采集和可视化。有鉴于此,Elastic 引入了强大的采集管道 Logstash 和灵活的可视化工具 Kibana。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">ELK日志系统数据流图如下:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;color: rgb(89, 89, 89);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 15px;letter-spacing: 0.75px;text-align: left;white-space: normal;"> <img data-ratio="0.4914586070959264" src="/upload/f2a988a869420b9ebf906ecd7629847.png" data-type="png" data-w="1522" style="margin-right: auto;margin-left: auto;display: block;width: 558px;"> <figcaption style="margin-top: 5px;text-align: center;color: rgb(136, 136, 136);font-size: 14px;"> ELK日志系统数据流图 </figcaption> </figure> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">简短了解 ELK 是个啥后,让我们一起动手搭建 ELK 实时日志分析平台,首先安装 Elasticsearch。</p> <blockquote data-tool="mdnice编辑器" style="margin: 10px 5px;padding: 10px 10px 10px 20px;border-left-color: rgb(53, 179, 120);color: rgb(97, 97, 97);font-size: 0.9em;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;overflow: auto;border-right: 0px solid rgb(53, 179, 120);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(53, 179, 120);">ELK 环境搭建版本很关键,建议统一版本,避免错误无处下手</strong>,我在这里选用的是 7.1.0 版本。</p> </blockquote> <h1 data-tool="mdnice编辑器" style="margin-top: 1.2em;margin-bottom: 1em;font-weight: bold;font-size: 28px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;color: rgb(53, 179, 120);">ElasticSearch 介绍与安装</h1> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">ElasticSearch 的介绍与安装在上一篇文章已经讲过了,这里就不进行赘述了,大家可以点击下方链接查看:</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;"><a href="https://mp.weixin.qq.com/s?__biz=MzU4Mjk0MjkxNA==&amp;mid=2247484538&amp;idx=1&amp;sn=53e4cbb49f2e98f123731e062ad49f67&amp;scene=21#wechat_redirect" data-linktype="2" style="color: rgb(53, 179, 120);box-sizing: border-box;background-color: rgb(255, 255, 255);outline: none;cursor: pointer;transition: color 0.3s ease 0s;touch-action: manipulation;overflow-wrap: break-word;font-weight: bold;border-bottom: 1px solid rgb(53, 179, 120);">全文搜索引擎 Elasticsearch 入门:集群搭建</a><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, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">如果你已经了解并安装好 Elasticsearch,那么就跟着我一起往下一步进发:了解并安装 Kibana。</p> <h1 data-tool="mdnice编辑器" style="margin-top: 1.2em;margin-bottom: 1em;font-weight: bold;font-size: 28px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;color: rgb(53, 179, 120);">Kibana 介绍与安装</h1> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">这部分主要讲解如何下载并安装 Kibana,以及如何安装 Kibana 插件,同时会针对 Kibana 的界面进行简单的介绍。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">首先让我们来看下 Kibana 究竟是何物?</p> <h2 data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 0rem;padding-top: 0.5em;padding-bottom: 0.5em;font-weight: bold;font-size: 23px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;line-height: 32px;color: rgb(53, 179, 120);display: inline-block;border-bottom: 0px solid rgb(53, 179, 120);border-top-color: rgb(53, 179, 120);border-right-color: rgb(53, 179, 120);border-left-color: rgb(53, 179, 120);">什么是 Kibana?</h2> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">Kibana 是为 Elasticsearch 设计的<strong style="color: rgb(53, 179, 120);">开源分析和可视化平台</strong>,你可以使用 Kibana 来搜索,查看存储在 Elasticsearch 索引中的数据并与之交互,你可以很容易实现高级的数据分析和可视化,以图标的形式展现出来。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">在简单了解了 Kibana 后,让我们来到 Kibana 的下载网站&nbsp;<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;overflow-wrap: break-word;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 179, 120);">https://www.elastic.co/cn/downloads/kibana</code>&nbsp;,目前使用的是 Windows 系统,因此下载 Windows 版本的 Kibana 下载包&nbsp;<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;overflow-wrap: break-word;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 179, 120);">kibana-7.1.0-windows-x86_64.zip</code>。</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;color: rgb(89, 89, 89);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 15px;letter-spacing: 0.75px;text-align: left;white-space: normal;"> <img data-ratio="0.9343589743589743" src="/upload/43559001b40786336078c24faec9463.png" data-type="png" data-w="975" style="margin-right: auto;margin-left: auto;height: 387px;display: block;width: 414px;"> </figure> <h2 data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 0rem;padding-top: 0.5em;padding-bottom: 0.5em;font-weight: bold;font-size: 23px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;line-height: 32px;color: rgb(53, 179, 120);display: inline-block;border-bottom: 0px solid rgb(53, 179, 120);border-top-color: rgb(53, 179, 120);border-right-color: rgb(53, 179, 120);border-left-color: rgb(53, 179, 120);">运行 Kibana</h2> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">下载完成后在本地解压,如果需要对 Kibana 做一些定制,可以在 config 目录下 编辑&nbsp;<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;overflow-wrap: break-word;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 179, 120);">kibana.yml</code>&nbsp;文件,在运行 Kibana 之前需要先运行 ElasticSearch(以下简称 ES),因为 Kibana 是基于 ES 运行的,现在进入 bin 目录下打开 kibana.bat 就可以运行 Kibana 了,我们现在打开浏览器,Kibana 是运行在 5601 端口上的,因此打开&nbsp;<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;overflow-wrap: break-word;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 179, 120);">http://localhost:5601</code>,打开后会出现如下页面:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;color: rgb(89, 89, 89);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 15px;letter-spacing: 0.75px;text-align: left;white-space: normal;"> <img data-ratio="0.36500943989930773" src="/upload/4dbdb1501d8a6e46b32674884ff1175a.png" data-type="png" data-w="1589" style="margin-right: auto;margin-left: auto;display: block;width: 558px;"> </figure> <h2 data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 0rem;padding-top: 0.5em;padding-bottom: 0.5em;font-weight: bold;font-size: 23px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;line-height: 32px;color: rgb(53, 179, 120);display: inline-block;border-bottom: 0px solid rgb(53, 179, 120);border-top-color: rgb(53, 179, 120);border-right-color: rgb(53, 179, 120);border-left-color: rgb(53, 179, 120);">导入样例数据,查看 Dashboard</h2> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">进入首页后会提示我们可以添加一些测试数据,ES 在 Kibana 开箱即用的版本中,已经为我们准备了三种样例数据,电商网站的订单,航空公司的飞行记录以及 WEB 网站的日志,我们可以点击 Add data,把他们添加进来,添加完成后,我们可以打开 Dashboards 界面,就可以看到系统已经为我们创建了数据的 Dashboard。</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;color: rgb(89, 89, 89);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 15px;letter-spacing: 0.75px;text-align: left;white-space: normal;"> <img data-ratio="0.45645645645645644" src="/upload/8713afcfe35c81be6a6c624a57c84d27.png" data-type="png" data-w="999" style="margin-right: auto;margin-left: auto;display: block;width: 558px;"> <figcaption style="margin-top: 5px;text-align: center;color: rgb(136, 136, 136);font-size: 14px;"> Dashboards </figcaption> </figure> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">第一个是电商的利润报表,我们可以打开来看一下:</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;color: rgb(89, 89, 89);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 15px;letter-spacing: 0.75px;text-align: left;white-space: normal;"> <img data-ratio="0.5046875" src="/upload/e88f9b4a9353609061d3e8f1d403df55.png" data-type="png" data-w="1920" style="margin-right: auto;margin-left: auto;display: block;width: 558px;"> </figure> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">在 Dashboard 中,我们可以将多套可视结果整合至单一页面内,而后提供搜索查询或者点击可视结果内的某元素指定过滤条件,从而实现结果过滤,Dashboard 能够帮助我们更全面地了解总体日志内容,并将各可视结果同日志关联起来,以上就是 Kibana 的 Dashboard 功能。</p> <h2 data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 0rem;padding-top: 0.5em;padding-bottom: 0.5em;font-weight: bold;font-size: 23px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;line-height: 32px;color: rgb(53, 179, 120);display: inline-block;border-bottom: 0px solid rgb(53, 179, 120);border-top-color: rgb(53, 179, 120);border-right-color: rgb(53, 179, 120);border-left-color: rgb(53, 179, 120);">Dev Tools</h2> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">接下来介绍 Kibana 里面非常有用的工具 Dev Tools,其实就是可以很方便地在 Kibana 中执行 ES 中的一些 API,比如我们上文讲到的检测有哪些节点在运行:<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;overflow-wrap: break-word;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 179, 120);">GET /_cat/nodes?v</code>,这样我们就能在 Kibana 中运行 ES 命令了。</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;color: rgb(89, 89, 89);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 15px;letter-spacing: 0.75px;text-align: left;white-space: normal;"> <img data-ratio="0.1648854961832061" src="/upload/6368d118a8cf8b2dcba113bd161ee7cd.png" data-type="png" data-w="1310" style="margin-right: auto;margin-left: auto;display: block;width: 558px;"> </figure> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">另外,Kibana 的 Dev Tools 还有许多的快捷菜单操作,比如&nbsp;<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;overflow-wrap: break-word;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 179, 120);">Ctrl + /</code>&nbsp;可以查看 API 帮助文档,其他的大家可以去自行摸索。</p> <h2 data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 0rem;padding-top: 0.5em;padding-bottom: 0.5em;font-weight: bold;font-size: 23px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;line-height: 32px;color: rgb(53, 179, 120);display: inline-block;border-bottom: 0px solid rgb(53, 179, 120);border-top-color: rgb(53, 179, 120);border-right-color: rgb(53, 179, 120);border-left-color: rgb(53, 179, 120);">安装与查看插件</h2> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">Kibana 可以通过插件的方式来提供一些 Kibana 中的特定应用或者增强图表展示的功能,Kibana 安装插件和 ES 非常相似。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">输入&nbsp;<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;overflow-wrap: break-word;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 179, 120);">kibana-plugin install kibana-plugin install https://github.com/sivasamyk/logtrail/releases/download/v0.1.31/logtrail-7.1.0-0.1.31.zip</code>&nbsp;就可以下载 LogTrail 插件了。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">在 cmd 中输入&nbsp;<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;overflow-wrap: break-word;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 179, 120);">kibana-plugin list</code>&nbsp;可以查看本机已安装的 Kibana 插件。</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;color: rgb(89, 89, 89);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 15px;letter-spacing: 0.75px;text-align: left;white-space: normal;"> <img data-ratio="0.13924050632911392" src="/upload/48c8b4e909091176ba0522186892a61e.png" data-type="png" data-w="395" style="margin-right: auto;margin-left: auto;display: block;width: 558px;"> </figure> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">如果想移除插件可以使用&nbsp;<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;overflow-wrap: break-word;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 179, 120);">kibana-plugin remove logtrail</code>&nbsp;命令来进行移除插件。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">到此为止,我们就下载并安装完成 Kibana,并对 Kibana 主要功能进行简单介绍,还介绍了 Dev Tools,大家可以自己在本地进行实践操作下。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">目前就差 ELK 三兄弟的最后一个:Logstash,让我们一起学习下。</p> <h1 data-tool="mdnice编辑器" style="margin-top: 1.2em;margin-bottom: 1em;font-weight: bold;font-size: 28px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;color: rgb(53, 179, 120);">Logstash 介绍与安装</h1> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">这部分主要是下载并安装 Logstash,并通过 Logstash 将测试数据集导入到 ES 中。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">话不多说,首先让我们来了解下 Logstash 是个啥?</p> <h2 data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 0rem;padding-top: 0.5em;padding-bottom: 0.5em;font-weight: bold;font-size: 23px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;line-height: 32px;color: rgb(53, 179, 120);display: inline-block;border-bottom: 0px solid rgb(53, 179, 120);border-top-color: rgb(53, 179, 120);border-right-color: rgb(53, 179, 120);border-left-color: rgb(53, 179, 120);">什么是 Logstash?</h2> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">Logstash 是开源的<strong style="color: rgb(53, 179, 120);">服务器端数据处理管道</strong>,能够同时从多个来源采集数据,转换数据,然后将数据发送到您最喜欢的存储库中。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">Logstash 能够<strong style="color: rgb(53, 179, 120);">动态地采集、转换和传输数据,不受格式或复杂度的影响</strong>。利用 Grok 从非结构化数据中派生出结构,从 IP 地址解码出地理坐标,匿名化或排除敏感字段,并简化整体处理过程。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">数据往往以各种各样的形式,或分散或集中地存在于很多系统中。Logstash 支持各种输入选择 ,可以在同一时间从众多常用来源捕捉事件,能够以连续的流式传输方式,轻松地从您的日志、指标、Web 应用、数据存储以及各种 AWS 服务采集数据。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">再了解过后,让我们去下载安装 Logstash。</p> <h2 data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 0rem;padding-top: 0.5em;padding-bottom: 0.5em;font-weight: bold;font-size: 23px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;line-height: 32px;color: rgb(53, 179, 120);display: inline-block;border-bottom: 0px solid rgb(53, 179, 120);border-top-color: rgb(53, 179, 120);border-right-color: rgb(53, 179, 120);border-left-color: rgb(53, 179, 120);">安装 Logstash</h2> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">还是来到 Logstash 的官网,进入到下载页面&nbsp;<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;overflow-wrap: break-word;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 179, 120);">https://www.elastic.co/cn/downloads/logstash</code>,下载的时候<strong style="color: rgb(53, 179, 120);">注意要和 ES 和 Kibana 的版本相同</strong>,这里下载的为 7.1.0 版本&nbsp;<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;overflow-wrap: break-word;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 179, 120);">logstash-7.1.0.zip</code>。</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;color: rgb(89, 89, 89);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 15px;letter-spacing: 0.75px;text-align: left;white-space: normal;"> <img data-ratio="0.9339901477832512" src="/upload/69dd6e56057e7418b55212d816adcc65.png" data-type="png" data-w="1015" style="margin-right: auto;margin-left: auto;height: 383px;display: block;width: 410px;"> </figure> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">下载后进行解压,也可以进入 conf 目录下修改&nbsp;<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;overflow-wrap: break-word;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 179, 120);">logstash.conf</code>&nbsp;进行配置,运行的时候可以通过指定配置文件&nbsp;<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;overflow-wrap: break-word;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 179, 120);">logstash -f logstash.conf</code>&nbsp;就可以执行数据的插入和转换的工作。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">再安装完成之后,让我们来使用 Logstash 往 ES 中导入数据。</p> <h2 data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 0rem;padding-top: 0.5em;padding-bottom: 0.5em;font-weight: bold;font-size: 23px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;line-height: 32px;color: rgb(53, 179, 120);display: inline-block;border-bottom: 0px solid rgb(53, 179, 120);border-top-color: rgb(53, 179, 120);border-right-color: rgb(53, 179, 120);border-left-color: rgb(53, 179, 120);">用 Logstash 导入 ES</h2> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">下面我们来导入测试数据集,首先修改&nbsp;<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;overflow-wrap: break-word;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 179, 120);">logstash.conf</code>&nbsp;文件,内容为:</p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> <pre class="code-snippet__js" data-lang=""><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">input {</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> file {</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> path =&gt; ["D:/SoftWare/logstash-7.1.0/csv/movies.csv"]</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> start_position =&gt; "beginning"</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> sincedb_path =&gt; "D:/SoftWare/logstash-7.1.0/csv/null"</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> }</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">}</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">filter {</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> csv {</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> separator =&gt; ","</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> columns =&gt; ["id","content","genre"]</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> }</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer"><br></span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> mutate {</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> split =&gt; { "genre" =&gt; "|" }</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> remove_field =&gt; ["path", "host","@timestamp","message"]</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> }</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer"><br></span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> mutate {</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer"><br></span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> split =&gt; ["content", "("]</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> add_field =&gt; { "title" =&gt; "%{[content][0]}"}</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> add_field =&gt; { "year" =&gt; "%{[content][1]}"}</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> }</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer"><br></span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> mutate {</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> convert =&gt; {</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> "year" =&gt; "integer"</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> }</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> strip =&gt; ["title"]</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> remove_field =&gt; ["path", "host","@timestamp","message","content"]</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> }</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer"><br></span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">}</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">output {</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> elasticsearch {</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> hosts =&gt; "http://localhost:9200"</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> index =&gt; "movies"</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> document_id =&gt; "%{id}"</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> }</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;"> stdout {}</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer" style="line-height: 26px;">}</span></code><code style="border-radius: 0px;"><span class="code-snippet_outer"><br></span></code></pre> </section> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">测试数据集来自 Movielens :<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;overflow-wrap: break-word;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 179, 120);">https://grouplens.org/datasets/movielens/</code>,大家可以前往下载。配置文件中的 path 根据自己下载的测试文件路径去修改。另外,配置文件的逻辑将在以后的文章中进行讲解。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">现在来执行命令&nbsp;<code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;font-size: 14px;overflow-wrap: break-word;border-radius: 4px;background-color: rgba(27, 31, 35, 0.05);font-family: &quot;Operator Mono&quot;, Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(53, 179, 120);">logstash -f logstash.conf</code>&nbsp;来把数据导入 ES。当看到数据打印到控制台时,数据也正在被写入 ES 中。</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;color: rgb(89, 89, 89);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 15px;letter-spacing: 0.75px;text-align: left;white-space: normal;"> <img data-ratio="0.5" src="/upload/82db718352b2c5416213c97c461c83b2.png" data-type="png" data-w="960" style="margin-right: auto;margin-left: auto;display: block;width: 558px;"> </figure> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">到此为止,我们就成功安装了 Logstash,并通过 Logstash 将测试数据集写入 ES,同时我们的 ELK 实时日志分析平台就搭建完成了。</p> <h2 data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 0rem;padding-top: 0.5em;padding-bottom: 0.5em;font-weight: bold;font-size: 23px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;line-height: 32px;color: rgb(53, 179, 120);display: inline-block;border-bottom: 0px solid rgb(53, 179, 120);border-top-color: rgb(53, 179, 120);border-right-color: rgb(53, 179, 120);border-left-color: rgb(53, 179, 120);">补充</h2> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">在通过 Logstash 将测试数据集写入 ES 后,小伙伴会发现 movies 索引状态为 yellow,不用担心,yellow 代表有副本分片没有被分配。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">因为只在本机之启动了一个节点,而 movies 的索引设置了一个主分片一个副本分片,主副分片是无法分配在一个节点上的。</p> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">解决方法:修改索引 setting,将副本 replica 设置成 0,或者为集群增加一个节点,状态就会变为 green。</p> <h1 data-tool="mdnice编辑器" style="margin-top: 1.2em;margin-bottom: 1em;font-weight: bold;font-size: 28px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;color: rgb(53, 179, 120);">总结</h1> <p data-tool="mdnice编辑器" style="margin: 1em 4px;padding-top: 8px;padding-bottom: 8px;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;letter-spacing: 0.75px;text-align: left;white-space: normal;font-size: 16px;line-height: 26px;color: black;">本文主要了解了什么是 ELK,然后通过实际操作和大家一起搭建了一个 ELK 日志分析平台,如果在搭建过程中有什么问题,欢迎留言交流讨论。<span style="text-align: center;color: rgb(51, 51, 51);font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 17px;">&nbsp;</span></p> <section style="font-size: 16px;color: black;padding: 10px;line-height: 1.6;letter-spacing: 0px;overflow-wrap: break-word;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;word-break: break-all;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;"> <section data-support="96编辑器" data-style-id="24435"> <section style="text-align: center;margin-top: 10px;margin-bottom: 10px;"> <section style="display:inline-block;background-color:#fefefe;width: 50%;" data-width="50%"> <p style="padding-top: 5px;padding-bottom: 5px;line-height: 26px;margin-right: auto;margin-left: auto;"><img data-ratio="0.204" src="/upload/6081f60ca484a01a5a44b04addbb1259.gif" data-type="gif" data-w="500" style="margin-right: auto;margin-left: auto;width: 100%;display: block;"></p> </section> <section style="margin-top: -20px;border-radius: 8px;border-style: solid;border-width: 2px;border-color: rgb(160, 201, 228);padding: 30px 15px;box-sizing: border-box;"> <p style="padding-top: 5px;padding-bottom: 5px;line-height: 26px;letter-spacing: 2px;text-align: left;"><span style="font-size: 14px;color: rgb(158, 162, 250);">●<a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzIzNzYxNDYzNw==&amp;mid=2247484298&amp;idx=1&amp;sn=a689113206c253b3053b42c92e29b183&amp;chksm=e8c4a0c8dfb329deebf4e673bd83632a309661918dccb3c590111eff1c74e811b76dbaa5b30e&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">Java中如何锁文件</a></span><span style="color: rgb(49, 178, 230);font-size: 14px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;widows: 1;"></span></p> <p style="padding-top: 5px;padding-bottom: 5px;line-height: 26px;letter-spacing: 2px;text-align: left;"><span style="font-size: 14px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;widows: 1;color: rgb(158, 162, 250);">●<a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzIzNzYxNDYzNw==&amp;mid=2247484291&amp;idx=1&amp;sn=b87bd2ff78a4a4e98f0f3bfcad23d89e&amp;chksm=e8c4a0c1dfb329d722235f9280c99f1f872f241442a9f3ce762ecedaaa12175784a5a4ef3970&amp;scene=21#wechat_redirect" data-itemshowtype="11" tab="innerlink" data-linktype="2">看完这篇还不会用Git,那我就哭了!</a></span><span style="font-size: 14px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;widows: 1;color: rgb(49, 178, 230);"></span></p> <p style="padding-top: 5px;padding-bottom: 5px;line-height: 26px;letter-spacing: 2px;text-align: left;"><span style="font-size: 14px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;widows: 1;color: rgb(158, 162, 250);">●<a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzIzNzYxNDYzNw==&amp;mid=2247484273&amp;idx=1&amp;sn=e5f5945ed01d6df98479fdb2f5f19677&amp;chksm=e8c4a033dfb329257f79add6cf3678d74ffd86dd1bd2c83b3023af023772626a5601df41d3ff&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">送给需要的你:Spring Doc 生成OPEN API 3文档</a></span><span style="font-size: 14px;font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;widows: 1;color: rgb(49, 178, 230);"></span></p> </section> </section> </section> <p style="text-align: center;"><span style="color: rgb(0, 82, 255);"><strong style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 14px;text-align: center;white-space: normal;"><span style="font-family: Roboto, Oxygen, Ubuntu, Cantarell, PingFangSC-light, PingFangTC-light, &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, sans-serif;text-align: start;background-color: rgb(255, 255, 255);">右上角按钮分享给更多人哦~</span></strong></span><span style="color: rgb(0, 82, 255);"><strong style="color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, &quot;PingFang SC&quot;, Cambria, Cochin, Georgia, Times, &quot;Times New Roman&quot;, serif;font-size: 14px;text-align: center;white-space: normal;"><span style="font-family: Roboto, Oxygen, Ubuntu, Cantarell, PingFangSC-light, PingFangTC-light, &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, sans-serif;text-align: start;background-color: rgb(255, 255, 255);"><img src="/upload/bdebeb96d99dba4b9471ab46678229a3.null" data-ratio="1" data-w="20" style="display: inline-block;width: 20px;vertical-align: text-bottom;"><img src="/upload/bdebeb96d99dba4b9471ab46678229a3.null" data-ratio="1" data-w="20" style="display: inline-block;width: 20px;vertical-align: text-bottom;"></span></strong></span></p> <p style="text-align: center;"><img class="rich_pages" data-backh="536" data-backw="536" data-before-oversubscription-url="https://mmbiz.qpic.cn/mmbiz_png/6tgwFZrjh8GgpNYZs1Ws7ILGYwwH7icyWXre2ic1lWWRsj4HYF6JcWLuaxfJwoI9VLHgdica3KnGs55qYGaBOLJKg/0?wx_fmt=png" data-copyright="0" data-ratio="1" data-s="300,640" src="/upload/96171a9cdb60d0b54d1dd9d212b93ae0.png" data-type="png" data-w="600" style="width: 100%;height: auto;"></p> <section data-support="96编辑器" data-style-id="23718"> <section style="margin-top: 10px;margin-bottom: 10px;text-align: right;"> <section style="display:inline-block;"> <section style="display: flex;justify-content:center;align-items: center;"> <section> <p><span style="letter-spacing: 2px;font-size: 14px;"><strong>来都来了,点个在看再走吧</strong></span><span style="font-size: 14px;letter-spacing:2px;"><strong>~~~</strong></span></p> <section style="width: 40px;height: 1px;background-color: rgb(98, 185, 221);"> <br> </section> <section style="margin-left: 20px;margin-top: 2px;width: 40px;height: 1px;background-color: rgb(98, 185, 221);"> <br> </section> </section> <section style="width: 30px;"> <img src="/upload/c1d500ea070276c9924fb89a506aafcc.gif" style="z-index: -1;cursor: pointer;vertical-align: middle;width: auto;" data-type="gif" data-ratio="1.1346153846153846" data-w="52"> </section> </section> </section> </section> </section> </section> <p><br></p>

从零到两百台服务器的创业野蛮生长史

作者:微信小助手

<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: 12px;color: rgb(136, 136, 136);font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;letter-spacing: 0.544px;">点击上方蓝色“</span><span style="font-size: 12px;font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;letter-spacing: 0.544px;color: rgb(0, 128, 255);">程序猿DD</span><span style="font-size: 12px;color: rgb(136, 136, 136);font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;letter-spacing: 0.544px;">”,选择“设为星标”</span><strong style="max-width: 100%;letter-spacing: 0.544px;color: rgb(74, 74, 74);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;font-size: 16px;white-space: pre-line;background-color: rgb(255, 255, 255);text-align: right;box-sizing: border-box !important;overflow-wrap: break-word !important;"></strong></p> <p style="max-width: 100%;min-height: 1em;white-space: normal;text-align: center;overflow-wrap: break-word !important;box-sizing: border-box !important;"><span style="font-size: 12px;"><span style="max-width: 100%;color: rgb(136, 136, 136);font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;letter-spacing: 0.544px;overflow-wrap: break-word !important;box-sizing: border-box !important;">回复“</span><span style="max-width: 100%;font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;letter-spacing: 0.544px;color: rgb(0, 128, 255);overflow-wrap: break-word !important;box-sizing: border-box !important;">资源</span><span style="max-width: 100%;color: rgb(136, 136, 136);font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;letter-spacing: 0.544px;overflow-wrap: break-word !important;box-sizing: border-box !important;">”获取独家整理的学习资料!</span></span></p> <p style="margin-top: 10px;margin-bottom: 10px;max-width: 100%;min-height: 1em;white-space: normal;text-align: center;overflow-wrap: break-word !important;box-sizing: border-box !important;"><span style="max-width: 100%;color: rgb(136, 136, 136);font-family: Georgia, &quot;Times New Roman&quot;, Times, &quot;Songti SC&quot;, serif;font-size: 14px;letter-spacing: 0.544px;overflow-wrap: break-word !important;box-sizing: border-box !important;"><img data-backh="34" data-backw="540" data-ratio="0.0625" data-s="300,640" data-type="jpeg" data-w="640" width="100%" src="/upload/8c292e55ba5a23cb6ebc11f2a2c4fece.null" style="font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;overflow-wrap: break-word !important;box-sizing: border-box !important;visibility: visible !important;width: 654px !important;"></span></p> <p style="max-width: 100%;min-height: 1em;white-space: normal;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);text-align: left;overflow-wrap: break-word !important;box-sizing: border-box !important;"><span style="font-size: 13px;max-width: 100%;letter-spacing: 0.544px;font-family: Optima-Regular, PingFangTC-light;color: rgb(178, 178, 178);overflow-wrap: break-word !important;box-sizing: border-box !important;"><img data-ratio="0.5628517823639775" src="/upload/47da0a5765067e5643598777fa45b6d2.jpg" data-type="jpeg" data-w="533"></span></p> <p style="max-width: 100%;min-height: 1em;white-space: normal;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);text-align: left;overflow-wrap: break-word !important;box-sizing: border-box !important;"><span style="font-size: 13px;max-width: 100%;letter-spacing: 0.544px;font-family: Optima-Regular, PingFangTC-light;color: rgb(178, 178, 178);overflow-wrap: break-word !important;box-sizing: border-box !important;">作者 |&nbsp;<span style="max-width: 100%;caret-color: rgb(136, 136, 136);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;text-align: right;text-size-adjust: auto;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;box-sizing: border-box !important;">杨钦民</span><br style="max-width: 100%;overflow-wrap: break-word !important;box-sizing: border-box !important;"></span></p> <section style="text-align: left;margin-bottom: 15px;max-width: 100%;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;box-sizing: border-box !important;"> <span style="max-width: 100%;letter-spacing: 0.544px;font-family: Optima-Regular, PingFangTC-light;color: rgb(178, 178, 178);font-size: 13px;overflow-wrap: break-word !important;box-sizing: border-box !important;">来源 |<span style="color: rgb(178, 178, 178);max-width: 100%;letter-spacing: 0.544px;font-family: Optima-Regular, PingFangTC-light;white-space: pre-line;overflow-wrap: break-word !important;box-sizing: border-box !important;">&nbsp;<span style="color: rgb(178, 178, 178);max-width: 100%;caret-color: rgb(136, 136, 136);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;text-align: right;text-size-adjust: auto;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;box-sizing: border-box !important;">zhuanlan.zhihu.com/p/33401898</span></span></span> </section> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;">贝聊成立于2013年,是中国幼儿园家长工作平台,致力于通过互联网产品及定制化解决方案,帮助幼儿园解决展示、通知、沟通等家长工作中的痛点,促进家园关系和谐。</span><span style="font-size: 15px;">贝聊是威创股份(A股幼教第一股)、清华启迪、网易联手投资的唯一品牌。</span><span style="font-size: 15px;">在短短几年内,用户规模迅速达到千万级别,每年DAU均呈倍数级增长。</span></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;">面对如此快速的发展,原有的技术架构很难支撑越来越复杂的业务场景,在系统可用性以及稳定性方面,都给贝聊技术团队带来了很大的压力。</span><span style="font-size: 15px;">因此,如何针对当前需求,选择合适的技术架构,保证架构平滑演进,值得我们深入思考。</span></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;">贝聊架构总体经历了三次重大历程,由几台服务器搭建的单体架构到目前的几百台分布式部署架构,在整个变化过程中,我们踩过了很多坑,遇到过很多重大技术挑战。</span></p> <h1 data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;padding-bottom: 0.3em;font-weight: bold;font-size: 1.4em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;text-align: left;white-space: normal;text-size-adjust: auto;border-bottom: 1px solid rgb(223, 226, 229);line-height: 1.6 !important;"><span style="font-size: 20px;line-height: 1.6 !important;">诞生期—技术架构选型V1.0</span></h1> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;">创业初期,我们的初始创业团队在进行架构选型时,主要基于以下几点进行考虑:</span></p> <ol data-tool="mdnice编辑器" class="list-paddingleft-2" style=""> <li> <section style="margin-top: 0.3em;margin-bottom: 0.3em;color: rgb(1, 1, 1);line-height: 1.6 !important;"> <span style="font-size: 15px;">在创业初期,研发资源有限,研发人力有限,技术储备有限,需要选择一个易维护、简单的技术架构;</span> </section></li> <li> <section style="margin-top: 0.3em;margin-bottom: 0.3em;color: rgb(1, 1, 1);line-height: 1.6 !important;"> <span style="font-size: 15px;">产品需要快速研发上线,并能够满足快速迭代要求,现实情况决定了一开始没有时间和精力来选择一个过于复杂的分布式架构系统,研发速度必须要快;</span> </section></li> <li> <section style="margin-top: 0.3em;margin-bottom: 0.3em;color: rgb(1, 1, 1);line-height: 1.6 !important;"> <span style="font-size: 15px;">创业初期,业务复杂度比较低,业务量也比较小,如果选择过于复杂的架构,反而会增加研发难度以及运维难度;</span> </section></li> <li> <section style="margin-top: 0.3em;margin-bottom: 0.3em;color: rgb(1, 1, 1);line-height: 1.6 !important;"> <span style="font-size: 15px;">遵从选择合适的技术而不是最好的技术原则,并权衡研发效率和产品目标,同时创业初期贝聊只有一个PHP研发人员,过于复杂的技术架构必然会带来比较高昂的学习成本。</span> </section></li> </ol> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;">正是基于以上几点考虑,最终选择了经典的LNMP技术架构,贝聊V1.0架构就这样诞生了,为了加快产品研发速度,尽快上线产品,首期通过外包公司实现了研发以及部署,后续由我们的PHP研发人员接手,并进行后续的迭代开发。</span></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><img data-ratio="0.7902777777777777" data-type="jpeg" data-w="720" src="/upload/d0d64676d15608f485dae270c9e48889.jpg" style="border-width: 0px;border-style: initial;border-color: initial;display: block;width: 657px;line-height: 1.6 !important;visibility: visible !important;top: auto;left: auto;right: auto;bottom: auto;"></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;">初期部署时,部署了三台ECS服务器,其中接入层nginx与系统部署在同一台机器,RDS数据库一台机器,Memcached缓存一台机器,V1.0架构具有以下特点:</span></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><img data-ratio="0.27175843694493784" data-type="jpeg" data-w="563" src="/upload/b9f4cfb342abaa68862a3b46ce2a693b.jpg" style="border-width: 0px;border-style: initial;border-color: initial;display: block;width: 563px;line-height: 1.6 !important;visibility: visible !important;top: auto;left: auto;right: auto;bottom: auto;"></p> <ul data-tool="mdnice编辑器" class="list-paddingleft-2" style=""> <li> <section style="margin-top: 0.3em;margin-bottom: 0.3em;color: rgb(1, 1, 1);line-height: 1.6 !important;"> <span style="font-size: 15px;">单体架构,架构简单,清晰的分层结构;</span> </section></li> <li> <section style="margin-top: 0.3em;margin-bottom: 0.3em;color: rgb(1, 1, 1);line-height: 1.6 !important;"> <span style="font-size: 15px;">可以快速研发,满足产品快速迭代要求;</span> </section></li> <li> <section style="margin-top: 0.3em;margin-bottom: 0.3em;color: rgb(1, 1, 1);line-height: 1.6 !important;"> <span style="font-size: 15px;">没有复杂的技术,技术学习成本低,同时运维成本低,无需专业的运维,节省开支。</span> </section></li> </ul> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;">LNMP架构支撑贝聊业务发展了将近一年半左右的时间,简单、易维护的架构为贝聊的快速发展做出了很大的贡献,期间业务发展迅速,用户体量也越来越大,原有架构逐渐暴露出越来越多的问题。</span></p> <h1 data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;padding-bottom: 0.3em;font-weight: bold;font-size: 1.4em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;text-align: left;white-space: normal;text-size-adjust: auto;border-bottom: 1px solid rgb(223, 226, 229);line-height: 1.6 !important;"><span style="font-size: 20px;line-height: 1.6 !important;">成长期—技术架构重构V2.0</span></h1> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;">我是在2015年初加入了贝聊,初始研发团队只有三人,有幸在这一时期</span></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;">主导了贝聊技术架构重构,并经历了贝聊后续的几次架构演进路程,将原有PHP单体架构重构为JAVA分布式架构。</span></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;">首先谈一谈我们做技术架构重构的契机,重构并非难在怎么做,而是难在何时开始做,所以我们做架构重构的契机主要基于以下几点:</span></p> <ol data-tool="mdnice编辑器" class="list-paddingleft-2" style=""> <li> <section style="margin-top: 0.3em;margin-bottom: 0.3em;color: rgb(1, 1, 1);line-height: 1.6 !important;"> <span style="font-size: 15px;">原有LNMP架构经历了两个团队研发和维护,外包团队和公司PHP研发人员,由于业务变化比较快,原有的数据库设计逐渐暴露出来很多问题,很多表设计不合理, 很多字段定义不清,比较混乱;</span> </section></li> <li> <section style="margin-top: 0.3em;margin-bottom: 0.3em;color: rgb(1, 1, 1);line-height: 1.6 !important;"> <span style="font-size: 15px;">2015年,由于业务发展,贝聊app需要拆分为两个客户端:</span> <span style="font-size: 15px;">贝聊家长端和贝聊老师端,通过不同的客户端来服务不同的用户群体,达到精准运营的目的,如果在原有架构上继续进行开发,则会导致新旧接口逻辑混在一起,并且早期的很多接口定义不是很规范,维护起来越来越麻烦、越来越吃力;</span> </section></li> <li> <section style="margin-top: 0.3em;margin-bottom: 0.3em;color: rgb(1, 1, 1);line-height: 1.6 !important;"> <span style="font-size: 15px;">原有API接口系统是单体架构,里面包含了各种接口,混合了各组业务逻辑处理,所有功能都集中在API接口系统中,代码非常臃肿,业务非常繁杂,迭代开发的速度也逐渐减慢,各种性能问题经常爆出,BUG也比较多,并且部署困难,任何修改每次都需整体部署。</span> <span style="font-size: 15px;">由于业务逻辑混杂在一起,新入职研发人员需要很长时间才能够完全熟悉系统,很难快速通过以点及面的方式切入系统;</span> </section></li> <li> <section style="margin-top: 0.3em;margin-bottom: 0.3em;color: rgb(1, 1, 1);line-height: 1.6 !important;"> <span style="font-size: 15px;">所有数据存储在一个RDS数据库中,只使用了一个主库,没有从库,同时很多系统共用一个数据库,一方面数据库没有做到物理上的隔离,另一方面很多表都放在了同一个数据库中,经常会碰到一个慢查询或者其他性能问题,导致整个RDS各项指标飙升,造成雪崩效应,所有系统连锁出现故障,最终都不能访问;</span> </section></li> <li> <section style="margin-top: 0.3em;margin-bottom: 0.3em;color: rgb(1, 1, 1);line-height: 1.6 !important;"> <span style="font-size: 15px;">公共服务耦合比较严重,很多第三方服务都散落在各个系统里面,不便于统一维护,当需要修改公共服务参数或者做其他调整时,需要深入到每个系统里进行修改或者排查,非常麻烦,还非常容易出现遗漏,最终产生BUG,急需独立拆分出公共服务,将公共服务从业务系统中解耦出来,由专人进行独立维护、独立部署;</span> </section></li> <li> <section style="margin-top: 0.3em;margin-bottom: 0.3em;color: rgb(1, 1, 1);line-height: 1.6 !important;"> <span style="font-size: 15px;">我们新的研发团队都拥有丰富的JAVA分布式架构设计经验,拥有高并发、高可用经验,因此将原有的单体架构重构为JAVA分布式架构也是顺势而为。</span> </section></li> </ol> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;">由于公司业务高速发展,如果停下来专门做技术架构重构是不可能的,我们选择了在维护现有系统的基础上,同时进行新的技术架构重构工作。</span><span style="font-size: 15px;">重构期间,在原有PHP研发团队的大力支援下,我们的重构工作还算非常顺利,既保障了业务的快速迭代需求,又成功完成了新的技术架构重构,新的V2.0架构如下:</span></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><img data-ratio="1.1152777777777778" data-type="jpeg" data-w="720" src="/upload/b5c0cc308d49dbff352d2484de1310e.jpg" style="border-width: 0px;border-style: initial;border-color: initial;display: block;width: 657px;line-height: 1.6 !important;visibility: visible !important;top: auto;left: auto;right: auto;bottom: auto;"></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;">在V2.0架构时期,初步实现了分布式部署架构,根据不同的功能以及业务逻辑,完成系统级别的拆分,同时对第三方服务进行解耦,拆分出了独立的服务模块,针对DB,我们实现了系统级拆分以及物理独立部署,并实现了数据库主从分离,同时引入了MQ消息队列,并使用SLB实现了负载均衡和带宽流量入口统一。</span></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;">V2.0时期的架构具有以下特点:</span></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><img data-ratio="0.5946902654867257" data-type="jpeg" data-w="565" src="/upload/653d289f057a51c05b0dd3dfca883583.jpg" style="border-width: 0px;border-style: initial;border-color: initial;display: block;width: 565px;line-height: 1.6 !important;visibility: visible !important;top: auto;left: auto;right: auto;bottom: auto;"></p> <ul data-tool="mdnice编辑器" class="list-paddingleft-2" style=""> <li> <section style="margin-top: 0.3em;margin-bottom: 0.3em;color: rgb(1, 1, 1);line-height: 1.6 !important;"> <span style="font-size: 15px;">分布式部署架构,系统易扩展;</span> </section></li> <li> <section style="margin-top: 0.3em;margin-bottom: 0.3em;color: rgb(1, 1, 1);line-height: 1.6 !important;"> <span style="font-size: 15px;">系统级拆分,拆分出业务功能逻辑独立的子系统,并独立拆分出DB;</span> </section></li> <li> <section style="margin-top: 0.3em;margin-bottom: 0.3em;color: rgb(1, 1, 1);line-height: 1.6 !important;"> <span style="font-size: 15px;">初步实现了服务化,系统间调用使用Hessian实现RPC;</span> </section></li> <li> <section style="margin-top: 0.3em;margin-bottom: 0.3em;color: rgb(1, 1, 1);line-height: 1.6 !important;"> <span style="font-size: 15px;">DB实现了物理隔离,避免以前单DB出故障,引发业务连锁故障,同时实现了数据库主从分离;</span> </section></li> <li> <section style="margin-top: 0.3em;margin-bottom: 0.3em;color: rgb(1, 1, 1);line-height: 1.6 !important;"> <span style="font-size: 15px;">引入MQ消息队列实现消息和任务异步化,加快接口响应速度,提升用户体验,同时针对一些消息推送任务也实现异步化,避免早期的轮询MySQL机制,减少消息推送延时,提升消息推送速度;</span> </section></li> <li> <section style="margin-top: 0.3em;margin-bottom: 0.3em;color: rgb(1, 1, 1);line-height: 1.6 !important;"> <span style="font-size: 15px;">使用SLB实现了Nginx负载均衡,在V1.0架构时期,我们的Nginx是单点部署,若一台Nginx服务器挂掉,则会影响很多业务系统,有单点故障风险,通过SLB实现多台Nginx负载均衡,达到高可用的目的,避免单点故障。</span> </section></li> </ul> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;"><strong style="line-height: 1.6 !important;">系统拆分和DB拆分</strong><strong style="line-height: 1.6 !important;"></strong></span></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;">针对系统拆分以及DB拆分,我们通过两个阶段来完成该项工作。</span></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;"><strong style="line-height: 1.6 !important;">第一阶段</strong><strong style="line-height: 1.6 !important;"></strong></span></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;">首先在系统层面进行拆分,将原有的大系统拆分出多个业务逻辑独立的子系统,而DB暂时不进行拆分,多套系统还继续共用一个DB,只是根据业务逻辑划分各个系统所依赖的表,不同业务逻辑系统之间不能互相访问表,这样新系统只访问自己所归属的表,通过此种方案,可以保证原有系统业务不受影响,同时新拆分的业务系统研发工作也可以顺利进行,此阶段大概花费了我们几个月的时间,最终顺利完成系统层面的拆分。</span></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;"><strong style="line-height: 1.6 !important;">第二阶段</strong><strong style="line-height: 1.6 !important;"></strong></span></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;">在完成系统层面拆分之后,我们紧接着实施DB层面的拆分,将各个子系统所依赖的表独立拆分出来,分别放置到不同的RDS数据库,实现物理的隔离,同时实现了数据库主从分离。</span><span style="font-size: 15px;">最终实现效果如下图:</span></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><img data-ratio="0.725" data-type="jpeg" data-w="720" src="/upload/2aab194954e8ad16b4d87417d9cff547.jpg" style="border-width: 0px;border-style: initial;border-color: initial;display: block;width: 657px;line-height: 1.6 !important;visibility: visible !important;top: auto;left: auto;right: auto;bottom: auto;"></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;"><strong style="line-height: 1.6 !important;">初步服务化</strong><strong style="line-height: 1.6 !important;"></strong></span></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;">本阶段,我们采用了比较简单易用的Hessian实现初期的RPC服务化。</span><span style="font-size: 15px;">针对第三方公共服务,从原有系统中解耦出来,独立拆分出服务化组件,并做独立部署,供其余业务系统统一调用。</span><span style="font-size: 15px;">而系统间调用也通过Hessian来实现RPC远程调用。</span></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;line-height: 1.6 !important;"><span style="font-size: 15px;"><strong style="line-height: 1.6 !important;">SLB负载均衡</strong><strong style="line-height: 1.6 !important;"></strong></span></p> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;caret-color: rgb(51, 51, 51);font-family: -apple-system, system-ui, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: inherit;text-align: left;white-space: normal;text-size-adjust: auto;l

简洁实用的Redis分布式锁用法

作者:微信小助手

<section data-mpa-template="t" style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 17px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 0.5440000295639038px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;text-decoration: none;"> <section data-mpa-template="t" style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <img data-backh="291" data-backw="578" data-ratio="0.503125" src="/upload/f1d6263865cbdab8e72d5bd02285d78.jpg" data-type="jpeg" data-w="640" style="width: 100%;height: auto;"> </section> </section> <section data-mpa-template="t" style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 17px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 0.544px;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;word-spacing: 0px;-moz-text-size-adjust: auto;-webkit-text-stroke-width: 0px;text-decoration: none;"> <br> </section> <section> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">在微服务中很多情况下需要使用到分布式锁功能,而目前比较常见的方案是通过Redis来实现分布式锁,网上关于分布式锁的实现方式有很多,早期主要是基于Redisson等客户端,但在Spring Boot2.x以上版本中使用Redis时,其客户端库已经默认使用lettuce。</span> <br> </section> <section> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">所以本文将直接介绍在Spring Boot2.x以上项目中快速使用Redis分布式锁的功能的方法,希望能够更新你的知识库!</span> </section> <p><span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;"><br></span></p> <p><br></p> <p style="text-align: center;">Redis分布式锁原理概述</p> <p style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;clear: both;min-height: 1em;text-align: center;"><img data-type="png" data-ratio="0.053125" data-w="640" src="/upload/16c3bc26d4547f0344ee22af769e1434.png" style="margin-top: 5px !important;margin-right: 0px;margin-bottom: 0px;margin-left: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;height: auto !important;color: rgb(60, 60, 60);font-weight: bold;letter-spacing: 1px;text-align: center;white-space: normal;background-color: rgb(255, 255, 255);font-size: 15px;display: inline-block;left: 0px;transform: rotateX(60deg);visibility: visible !important;width: 632px !important;"></p> <p><br></p> <section> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">实际上Redis服务本身并不提供分布式锁这样的机制,但是作为全局Key-Value存储系统,客户端可以利用Redis提供的基本功能并通过一定的算法设计来实现分布式锁功能。</span> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">目前已有不少博客文章及代码库描述了如何使用Redis来实现分布式锁,但是许多实现相对比较简单,安全性也比较低。</span> </section> <section style="text-align: left;line-height: 2em;"> <br> </section> <section> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">在Redis的官方文档中推荐了一种叫做RedLock的算法来实现基于Redis的分布式锁功能,现阶段已存在基于该算法的多种语言版本的Redis客户端实现库。</span> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">其中Java领域最为知名的是Redisson库。</span> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">但由于Redisson不仅实现了分布式锁功能,还额外实现了一套Redis分布式数据结构,因此会显得比较重,加上最新的基于Spring Boot.2.x以上版本使用Redis时,其客户端库已经默认使用了lettuce(比Redisson、Jedis线程更安全、更轻量级的一种Java Redis客户端库)的封装,所以为了更加符合微服务场景下的使用,在实践中往往会选择基于RedLock算法自行实现分布式锁。</span> <br> <br> </section> <section> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">本案例也将演示如何RedLock算法来实现Redis分布式锁功能,不过在此之前让我们先来看看RedLock算法是如何运行的,示意图如下:</span> <br> </section> <p style="text-align: justify;text-indent: 28px;line-height: 21px;"><br></p> <p style="text-align: center;"><img class="rich_pages" data-ratio="1.4172709294660515" data-s="300,640" src="/upload/9e2fd47e0289735ec0ab1cf7c9f66e81.png" data-type="png" data-w="1517" style=""></p> <p style="text-align: center;"><br></p> <section> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">以上就是实现Redis分布式锁官方推荐的RedLock算法逻辑,它是一种多节点Redis的分布式锁算法,可以有效防止单节点故障问题。</span> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">其执行步骤说明如下:</span> </section> <ul class="list-paddingleft-2" style=""> <li> <section> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">首先Redis客户端获取当前系统时间,以毫秒为单位;</span> </section></li> <li> <section> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">然后客户端会顺序地尝试向Redis集群中的每个节点获取锁,其具体步骤是使用相同的键Key名和随机值;</span> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">在向每个Redis节点获取锁的过程中,客户端会以比锁过期时间小得多的时间来设定超时机制,例如锁的整个超时时间为10秒,集群有5个节点,那么每个节点获取锁的超时时间可能会被限制在5~50毫秒之间,这是为了防止在某个节点不可用的情况下,客户端等待时间过长,造成性能阻塞;</span> </section></li> <li> <section> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">之后随着各节点获取锁结果的反馈,Redis客户端会对获取情况进行判断,如果获取各节点锁的总时间小于锁的超时时间设置,并且成功获取锁的节点数目大于N/2+1个(例如5个节点至少要有3个节点成功获取锁),满足上述条件的情况下,Redis客户端才会认为获取锁成功,否则就会认为锁获取失败,并依次释放掉各个节点的锁信息;</span> </section></li> <li> <section> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">获取锁成功后即可以安全地执行操作,完成后再依次释放各节点锁持有的锁信息;</span> </section></li> </ul> <section> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">&nbsp;</span> </section> <section> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">实现上述算法的Redis客户端可以基本上保证分布式锁的有效性及安全性的几个基本特性要求:</span> </section> <ul class="list-paddingleft-2" style=""> <li> <section> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">互斥:</span> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">任何时刻只能有一个Redis客户端获取锁;</span> </section></li> <li> <section> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">无死锁:</span> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">即使锁定资源的服务崩溃或者分区,仍然能释放锁);</span> </section></li> <li> <section> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">容错性:</span> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">只要多数redis节点(一半以上)在使用,Redis客户端就可以获取和释放锁;</span> </section></li> </ul> <p><span style="font-size: 16px;"><span style="font-size: 16px;margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;font-style: normal;font-variant-caps: normal;font-weight: normal;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;word-spacing: 0px;-moz-text-size-adjust: auto;-webkit-text-stroke-width: 0px;text-decoration: none;color: rgb(63, 63, 63);font-family: PingFangSC-Light;letter-spacing: 1px;background-color: rgb(255, 255, 255);"><br></span></span></p> <p style="text-align: center;">Spring Boot集成使用方式<br></p> <p style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;clear: both;min-height: 1em;text-align: center;"><img data-type="png" data-ratio="0.053125" data-w="640" src="/upload/16c3bc26d4547f0344ee22af769e1434.png" style="margin-top: 5px !important;margin-right: 0px;margin-bottom: 0px;margin-left: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;height: auto !important;color: rgb(60, 60, 60);font-weight: bold;letter-spacing: 1px;text-align: center;white-space: normal;background-color: rgb(255, 255, 255);font-size: 15px;display: inline-block;left: 0px;transform: rotateX(60deg);visibility: visible !important;width: 632px !important;"></p> <p><span style="font-size:16px;font-family:宋体;"><br></span></p> <section> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">通过前面内容的描述,相信你对实现Redis分布式锁的基本算法应该有了一定的认识和理解。</span> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">而在实践的过程中可以依据该算法自行定制实现,但实际上Spring早就提供了基于该算法的Redis的分布式锁的实现。</span> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">其具体使用步骤如下:<br></span> <br> <span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">1)在工程pom.xml文件中引入Spring Integration依赖,代码如下:</span> </section> <section style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;word-spacing: 0px;letter-spacing: 0px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;margin: 0px;padding: 0px;"><code style="overflow-wrap: break-word;margin: 0px 2px;line-height: 18px;font-size: 14px;font-weight: normal;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) none repeat scroll 0% 0%;overflow-x: auto;padding: 0.5em;white-space: pre !important;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(128, 128, 128);word-wrap: inherit !important;word-break: inherit !important;">&lt;!--&nbsp;spring&nbsp;integration&nbsp;--&gt;</span><br><span style="font-size: inherit;color: inherit;line-height: inherit;margin: 0px;padding: 0px;word-wrap: inherit !important;word-break: inherit !important;">&lt;<span style="line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">dependency</span>&gt;</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;color: inherit;line-height: inherit;margin: 0px;padding: 0px;word-wrap: inherit !important;word-break: inherit !important;">&lt;<span style="line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">groupId</span>&gt;</span>org.springframework.boot<span style="font-size: inherit;color: inherit;line-height: inherit;margin: 0px;padding: 0px;word-wrap: inherit !important;word-break: inherit !important;">&lt;/<span style="line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">groupId</span>&gt;</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;color: inherit;line-height: inherit;margin: 0px;padding: 0px;word-wrap: inherit !important;word-break: inherit !important;">&lt;<span style="line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">artifactId</span>&gt;</span>spring-boot-starter-integration<span style="font-size: inherit;color: inherit;line-height: inherit;margin: 0px;padding: 0px;word-wrap: inherit !important;word-break: inherit !important;">&lt;/<span style="line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">artifactId</span>&gt;</span><br><span style="font-size: inherit;color: inherit;line-height: inherit;margin: 0px;padding: 0px;word-wrap: inherit !important;word-break: inherit !important;">&lt;/<span style="line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">dependency</span>&gt;</span><br><span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(128, 128, 128);word-wrap: inherit !important;word-break: inherit !important;">&lt;!--&nbsp;spring&nbsp;integration与redis结合,实现redis分布式锁&nbsp;--&gt;</span><br><span style="font-size: inherit;color: inherit;line-height: inherit;margin: 0px;padding: 0px;word-wrap: inherit !important;word-break: inherit !important;">&lt;<span style="line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">dependency</span>&gt;</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;color: inherit;line-height: inherit;margin: 0px;padding: 0px;word-wrap: inherit !important;word-break: inherit !important;">&lt;<span style="line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">groupId</span>&gt;</span>org.springframework.integration<span style="font-size: inherit;color: inherit;line-height: inherit;margin: 0px;padding: 0px;word-wrap: inherit !important;word-break: inherit !important;">&lt;/<span style="line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">groupId</span>&gt;</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;color: inherit;line-height: inherit;margin: 0px;padding: 0px;word-wrap: inherit !important;word-break: inherit !important;">&lt;<span style="line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">artifactId</span>&gt;</span>spring-integration-redis<span style="font-size: inherit;color: inherit;line-height: inherit;margin: 0px;padding: 0px;word-wrap: inherit !important;word-break: inherit !important;">&lt;/<span style="line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">artifactId</span>&gt;</span><br><span style="font-size: inherit;color: inherit;line-height: inherit;margin: 0px;padding: 0px;word-wrap: inherit !important;word-break: inherit !important;">&lt;/<span style="line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">dependency</span>&gt;</span><br></code></pre> </section> <p><span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">目前Spring所提供的分布式锁相关的代码被迁移在Spring Integration子项目中,所以这里引入其相关依赖。</span></p> <p><span style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-style: normal;font-variant-caps: normal;font-weight: normal;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;text-decoration: none;color: rgb(63, 63, 63);font-family: PingFangSC-Light;font-size: 15px;letter-spacing: 1px;background-color: rgb(255, 255, 255);"><br></span></p> <p><span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">2)编写RedisLock的配置类,代码如下:</span></p> <section style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;word-spacing: 0px;letter-spacing: 0px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;margin: 0px;padding: 0px;"><code style="overflow-wrap: break-word;margin: 0px 2px;line-height: 18px;font-size: 14px;font-weight: normal;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) none repeat scroll 0% 0%;overflow-x: auto;padding: 0.5em;white-space: pre !important;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(91, 218, 237);word-wrap: inherit !important;word-break: inherit !important;">@Configuration</span><br><span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">public</span>&nbsp;<span style="font-size: inherit;color: inherit;line-height: inherit;margin: 0px;padding: 0px;word-wrap: inherit !important;word-break: inherit !important;"><span style="line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">class</span>&nbsp;<span style="line-height: inherit;margin: 0px;padding: 0px;color: rgb(165, 218, 45);overflow-wrap: inherit !important;word-break: inherit !important;">RedisLockConfiguration</span>&nbsp;</span>{<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(91, 218, 237);word-wrap: inherit !important;word-break: inherit !important;">@Bean</span><br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;"><span style="line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">public</span>&nbsp;RedisLockRegistry&nbsp;<span style="line-height: inherit;margin: 0px;padding: 0px;color: rgb(165, 218, 45);overflow-wrap: inherit !important;word-break: inherit !important;">redisLockRegistry</span><span style="line-height: inherit;margin: 0px;padding: 0px;color: rgb(255, 152, 35);overflow-wrap: inherit !important;word-break: inherit !important;">(RedisConnectionFactory&nbsp;redisConnectionFactory)</span>&nbsp;</span>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">return</span>&nbsp;<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">new</span>&nbsp;RedisLockRegistry(redisConnectionFactory,&nbsp;<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">"payment"</span>);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}</code></pre> </section> <p><span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">以上配置代码加载的前提在于应用已经集成了Redis服务访问链接信息,具体Spring Boot项目集成Redis访问的方式比较简单可以参考其他资料。</span><br></p> <p><br></p> <p><span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">3)分布式锁的具体使用方式,代码片段如下:</span></p> <section style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;word-spacing: 0px;letter-spacing: 0px;font-family: &quot;Helvetica Neue&quot;, Helvetica, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;margin: 0px;padding: 0px;"><code style="overflow-wrap: break-word;margin: 0px 2px;line-height: 18px;font-size: 14px;font-weight: normal;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) none repeat scroll 0% 0%;overflow-x: auto;padding: 0.5em;white-space: pre !important;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;display: -webkit-box !important;"><span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(128, 128, 128);word-wrap: inherit !important;word-break: inherit !important;">/**<br>&nbsp;*&nbsp;引入Redis分布式锁依赖组件<br>&nbsp;*/</span><br>@Autowired<br><span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">private</span>&nbsp;RedisLockRegistry&nbsp;redisLockRegistry;<br><br>@<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">Override<br><span style="line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);overflow-wrap: inherit !important;word-break: inherit !important;">public</span>&nbsp;UnifiedPayBO&nbsp;<span style="line-height: inherit;margin: 0px;padding: 0px;color: rgb(165, 218, 45);overflow-wrap: inherit !important;word-break: inherit !important;">unifiedPay</span>(<span style="line-height: inherit;margin: 0px;padding: 0px;color: rgb(255, 152, 35);overflow-wrap: inherit !important;word-break: inherit !important;">UnifiedPayDTO&nbsp;unifiedPayDTO</span>)&nbsp;</span>{<br>&nbsp;&nbsp;&nbsp;&nbsp;...<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(128, 128, 128);word-wrap: inherit !important;word-break: inherit !important;">//创建Redis分布式锁</span><br>&nbsp;&nbsp;&nbsp;&nbsp;Lock&nbsp;<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">lock</span>&nbsp;=&nbsp;redisLockRegistry.obtain(redisLockPrefix&nbsp;+&nbsp;unifiedPayDTO.getOrderId());<br>&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">try</span>&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(128, 128, 128);word-wrap: inherit !important;word-break: inherit !important;">//尝试获取锁</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boolean&nbsp;isLock&nbsp;=&nbsp;<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">lock</span>.tryLock(<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">1</span>,&nbsp;TimeUnit.SECONDS);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">if</span>&nbsp;(isLock)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(128, 128, 128);word-wrap: inherit !important;word-break: inherit !important;">//执行业务逻辑</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">catch</span>&nbsp;(InterruptedException&nbsp;e)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">finally</span>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(128, 128, 128);word-wrap: inherit !important;word-break: inherit !important;">//释放分布式锁</span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: inherit;line-height: inherit;margin: 0px;padding: 0px;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">lock</span>.unlock();<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;...<br>}<br></code></pre> </section> <p><span style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-style: normal;font-variant-caps: normal;font-weight: normal;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;text-decoration: none;color: rgb(63, 63, 63);font-family: PingFangSC-Light;font-size: 15px;letter-spacing: 1px;background-color: rgb(255, 255, 255);"><br></span></p> <p><span style="caret-color: rgb(60, 60, 60);color: rgb(60, 60, 60);font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 15px;font-style: normal;font-variant-caps: normal;font-weight: normal;letter-spacing: 1px;orphans: auto;text-align: justify;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-size-adjust: auto;-webkit-text-stroke-width: 0px;background-color: rgb(255, 255, 255);text-decoration: none;display: inline !important;float: none;">上述代码为订单防重时使用Redis分布锁的示例代码,通过依赖注入RedisLockRegistry实例来实现分布式锁的相关操作,例如obtain()方法创建锁、tryLock()持有锁及unlock()释放锁等。</span><br><br style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"></p> <p style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;clear: both;min-height: 1em;white-space: normal;line-height: 20.48px;text-align: center;"><br style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"></p> <p style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;clear: both;min-height: 1em;white-space: normal;line-height: 28.4444px;text-align: center;"><span style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 18px;line-height: 1.6;">—————END—————</span></p> <p style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;clear: both;min-height: 1em;white-space: normal;line-height: 28.4444px;text-align: center;"><span style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;font-size: 17.7778px;line-height: 32px;"><br style="margin: 0px;padding: 0px;max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"></span></p> <p style="text-align: center;"><img class="rich_pages" data-ratio="0.735357917570499" data-s="300,640" data-type="png" data-w="461" style="visibility: visible !important;width: 461px !important;height: auto !important;" src="/upload/97fc3d83f3f707ee59412aefb98132d8.png"><br></p> <p> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br></p>

Tomcat面试题(2020最新版)

作者:微信小助手

<h2 style="box-sizing: border-box;outline: 0px;margin-top: 8px;margin-bottom: 16px;font-size: 24px;font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;color: rgb(79, 79, 79);font-weight: 700;line-height: 32px;overflow-wrap: break-word;font-variant-ligatures: common-ligatures;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">Tomcat是什么?</h2> <p style="box-sizing: border-box;outline: 0px;margin-bottom: 16px;font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;font-size: 16px;color: rgb(77, 77, 77);line-height: 26px;overflow-wrap: break-word;font-variant-ligatures: common-ligatures;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">Tomcat 服务器Apache软件基金会项目中的一个核心项目,是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。</p> <h2 style="box-sizing: border-box;outline: 0px;margin-top: 8px;margin-bottom: 16px;font-size: 24px;font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;color: rgb(79, 79, 79);font-weight: 700;line-height: 32px;overflow-wrap: break-word;font-variant-ligatures: common-ligatures;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">Tomcat的缺省端口是多少,怎么修改</h2> <ol class="list-paddingleft-2" style="list-style-type: decimal;"> <li><p>找到Tomcat目录下的conf文件夹</p></li> <li><p>进入conf文件夹里面找到server.xml文件</p></li> <li><p>打开server.xml文件</p></li> <li><p>在server.xml文件里面找到下列信息</p></li> <li><p>把Connector标签的8080端口改成你想要的端口</p></li> </ol> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> <li></li> <li></li> <li></li> <li></li> </ul> <pre class="code-snippet__js" data-lang="xml"><code><span class="code-snippet_outer"><span class="code-snippet__tag">&lt;<span class="code-snippet__name">Service</span> <span class="code-snippet__attr">name</span>=<span class="code-snippet__string">"Catalina"</span>&gt;</span></span></code><code><span class="code-snippet_outer"><span class="code-snippet__tag">&lt;<span class="code-snippet__name">Connector</span> <span class="code-snippet__attr">port</span>=<span class="code-snippet__string">"8080"</span> <span class="code-snippet__attr">protocol</span>=<span class="code-snippet__string">"HTTP/1.1"</span> </span></span></code><code><span class="code-snippet_outer"> <span class="code-snippet__attr">connectionTimeout</span>=<span class="code-snippet__string">"20000"</span> </span></code><code><span class="code-snippet_outer">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="code-snippet__attr">redirectPort</span>=<span class="code-snippet__string">"8443"</span>&nbsp;/&gt;</span></code></pre> </section> <h2 style="box-sizing: border-box;outline: 0px;margin-top: 8px;margin-bottom: 16px;font-size: 24px;font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;color: rgb(79, 79, 79);font-weight: 700;line-height: 32px;overflow-wrap: break-word;font-variant-ligatures: common-ligatures;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">tomcat 有哪几种Connector 运行模式(优化)?</h2> <p style="box-sizing: border-box;outline: 0px;margin-bottom: 16px;font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;font-size: 16px;color: rgb(77, 77, 77);line-height: 26px;overflow-wrap: break-word;font-variant-ligatures: common-ligatures;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">下面,我们先大致了解Tomcat Connector的三种运行模式。</p> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p><span style="box-sizing: border-box;outline: 0px;font-weight: 700;overflow-wrap: break-word;">BIO:同步并阻塞</span>&nbsp;一个线程处理一个请求。缺点:并发量高时,线程数较多,浪费资源。Tomcat7或以下,在Linux系统中默认使用这种方式。</p></li> </ul> <p style="box-sizing: border-box;outline: 0px;margin-bottom: 16px;font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;font-size: 16px;color: rgb(77, 77, 77);line-height: 26px;overflow-wrap: break-word;font-variant-ligatures: common-ligatures;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">&nbsp;<span style="box-sizing: border-box;outline: 0px;font-weight: 700;overflow-wrap: break-word;">配制项</span>:protocol=”HTTP/1.1”</p> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p>NIO:同步非阻塞IO</p></li> </ul> <p><br></p> <p>利用Java的异步IO处理,可以通过少量的线程处理大量的请求,可以复用同一个线程处理多个connection(多路复用)。</p> <p><br></p> <p>Tomcat8在Linux系统中默认使用这种方式。</p> <p><br></p> <p>Tomcat7必须修改Connector配置来启动。</p> <p><br></p> <p>配制项:protocol=”org.apache.coyote.http11.Http11NioProtocol”</p> <p><br></p> <p>备注:我们常用的Jetty,Mina,ZooKeeper等都是基于java nio实现.</p> <p><br></p> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p>APR:即Apache Portable Runtime,从操作系统层面解决io阻塞问题。**AIO方式,**异步非阻塞IO(Java NIO2又叫AIO) 主要与NIO的区别主要是操作系统的底层区别.可以做个比喻:比作快递,NIO就是网购后要自己到官网查下快递是否已经到了(可能是多次),然后自己去取快递;AIO就是快递员送货上门了(不用关注快递进度)。</p></li> </ul> <p><br></p> <p>配制项:protocol=”org.apache.coyote.http11.Http11AprProtocol”</p> <p><br></p> <p>备注:需在本地服务器安装APR库。Tomcat7或Tomcat8在Win7或以上的系统中启动默认使用这种方式。Linux如果安装了apr和native,Tomcat直接启动就支持apr。</p> <p><br></p> <h2 style="box-sizing: border-box;outline: 0px;margin-top: 8px;margin-bottom: 16px;font-size: 24px;font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;color: rgb(79, 79, 79);font-weight: 700;line-height: 32px;overflow-wrap: break-word;font-variant-ligatures: common-ligatures;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">Tomcat有几种部署方式?</h2> <p style="box-sizing: border-box;outline: 0px;margin-bottom: 16px;font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;font-size: 16px;color: rgb(77, 77, 77);line-height: 26px;overflow-wrap: break-word;font-variant-ligatures: common-ligatures;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"><span style="box-sizing: border-box;outline: 0px;font-weight: 700;overflow-wrap: break-word;">在Tomcat中部署Web应用的方式主要有如下几种:</span></p> <ul class="list-paddingleft-2" style="list-style-type: square;"> <li><p>利用Tomcat的自动部署。</p></li> </ul> <p>把web应用拷贝到webapps目录。Tomcat在启动时会加载目录下的应用,并将编译后的结果放入work目录下。</p> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p>使用Manager App控制台部署。</p></li> </ul> <p>在tomcat主页点击“Manager App” 进入应用管理控制台,可以指定一个web应用的路径或war文件。</p> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p>修改conf/server.xml文件部署。</p></li> </ul> <p>修改conf/server.xml文件,增加Context节点可以部署应用。<br></p> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p>增加自定义的Web部署文件。<br></p></li> </ul> <p>在conf/Catalina/localhost/ 路径下增加 xyz.xml文件,内容是Context节点,可以部署应用。<br></p> <p><br></p> <h2 style="box-sizing: border-box;outline: 0px;margin-top: 8px;margin-bottom: 16px;font-size: 24px;font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;color: rgb(79, 79, 79);font-weight: 700;line-height: 32px;overflow-wrap: break-word;font-variant-ligatures: common-ligatures;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">tomcat容器是如何创建servlet类实例?用到了什么原理?</h2> <ol class="list-paddingleft-2" style="list-style-type: decimal;"> <li><p>当容器启动时,会读取在webapps目录下所有的web应用中的web.xml文件,然后对 xml文件进行解析,并读取servlet注册信息。然后,将每个应用中注册的servlet类都进行加载,并通过 反射的方式实例化。(有时候也是在第一次请求时实例化)</p></li> <li><p>在servlet注册时加上1如果为正数,则在一开始就实例化,如果不写或为负数,则第一次请求实例化。</p></li> </ol> <h2 style="box-sizing: border-box;outline: 0px;margin-top: 8px;margin-bottom: 16px;font-size: 24px;font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;color: rgb(79, 79, 79);font-weight: 700;line-height: 32px;overflow-wrap: break-word;font-variant-ligatures: common-ligatures;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">Tomcat工作模式</h2> <p style="box-sizing: border-box;outline: 0px;margin-bottom: 16px;font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;font-size: 16px;color: rgb(77, 77, 77);line-height: 26px;overflow-wrap: break-word;font-variant-ligatures: common-ligatures;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">Tomcat作为servlet容器,有三种工作模式:</p> <p>1、独立的servlet容器,servlet容器是web服务器的一部分;</p> <p>2、进程内的servlet容器,servlet容器是作为web服务器的插件和java容器的实现,web服务器插件在内部地址空间打开一个jvm使得java容器在内部得以运行。反应速度快但伸缩性不足;</p> <p>3、进程外的servlet容器,servlet容器运行于web服务器之外的地址空间,并作为web服务器的插件和java容器实现的结合。反应时间不如进程内但伸缩性和稳定性比进程内优;</p> <p style="box-sizing: border-box;outline: 0px;margin-bottom: 16px;font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;font-size: 16px;color: rgb(77, 77, 77);line-height: 26px;overflow-wrap: break-word;font-variant-ligatures: common-ligatures;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"><strong>进入Tomcat的请求可以根据Tomcat的工作模式分为如下两类:</strong></p> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p>Tomcat作为应用程序服务器:请求来自于前端的web服务器,这可能是Apache, IIS, Nginx等;</p></li> <li><p>Tomcat作为独立服务器:请求来自于web浏览器;</p><p><br></p></li> </ul> <p><br></p> <p>面试时问到Tomcat相关问题的几率并不高,正式因为如此,很多人忽略了对Tomcat相关技能的掌握,下面这一篇文章整理了Tomcat相关的系统架构,介绍了Server、Service、Connector、Container之间的关系,各个模块的功能,可以说把这几个掌握住了,Tomcat相关的面试题你就不会有任何问题了!另外,在面试的时候你还要有意识无意识的往Tomcat这个地方引,就比如说常见的Spring MVC的执行流程,一个URL的完整调用链路,这些相关的题目你是可以往Tomcat处理请求的这个过程去说的!掌握了Tomcat这些技能,面试官一定会佩服你的!</p> <p><br></p> <p>学了本章之后你应该明白的是:</p> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p>Server、Service、Connector、Container四大组件之间的关系和联系,以及他们的主要功能点;</p></li> <li><p>Tomcat执行的整体架构,请求是如何被一步步处理的;</p></li> <li><p>Engine、Host、Context、Wrapper相关的概念关系;</p></li> <li><p>Container是如何处理请求的;</p></li> <li><p>Tomcat用到的相关设计模式;</p></li> </ul> <p><br></p> <p><br></p> <h2 style="box-sizing: border-box;outline: 0px;margin-top: 8px;margin-bottom: 16px;font-size: 24px;font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;color: rgb(79, 79, 79);font-weight: 700;line-height: 32px;overflow-wrap: break-word;font-variant-ligatures: common-ligatures;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">Tomcat顶层架构</h2> <p>俗话说,站在巨人的肩膀上看世界,一般学习的时候也是先总览一下整体,然后逐个部分个个击破,最后形成思路,了解具体细节,Tomcat的结构很复杂,但是 Tomcat 非常的模块化,找到了 Tomcat 最核心的模块,问题才可以游刃而解,了解了 Tomcat 的整体架构对以后深入了解 Tomcat 来说至关重要!</p> <p><br></p> <p>先上一张Tomcat的顶层结构图(图A),如下:</p> <p><br></p> <p><img data-ratio="0.785" src="/upload/588a3a8e5aeb59847c0efea7e017666.png" data-type="png" data-w="600"></p> <p>Tomcat中最顶层的容器是Server,代表着整个服务器,从上图中可以看出,一个Server可以包含至少一个Service,即可以包含多个Service,用于具体提供服务。</p> <p><br></p> <p>Service主要包含两个部分:Connector和Container。从上图中可以看出 Tomcat 的心脏就是这两个组件,他们的作用如下:</p> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p>Connector用于处理连接相关的事情,并提供Socket与Request请求和Response响应相关的转化;</p></li> <li><p>Container用于封装和管理Servlet,以及具体处理Request请求;</p></li> </ul> <p><br></p> <p>一个Tomcat中只有一个Server,一个Server可以包含多个Service,一个Service只有一个Container,但是可以有多个Connectors,这是因为一个服务可以有多个连接,如同时提供Http和Https链接,也可以提供向相同协议不同端口的连接,示意图如下(Engine、Host、Context下面会说到):</p> <p><img data-ratio="0.7031963470319634" src="/upload/d1a8461e7a102f68500e04301fc6ebf5.png" data-type="png" data-w="438"></p> <p>多个 Connector 和一个 Container 就形成了一个 Service,有了 Service 就可以对外提供服务了,但是 Service 还要一个生存的环境,必须要有人能够给她生命、掌握其生死大权,那就非 Server 莫属了!所以整个 Tomcat 的生命周期由 Server 控制。</p> <p><br></p> <p>另外,上述的包含关系或者说是父子关系,都可以在tomcat的conf目录下的server.xml配置文件中看出,下图是删除了注释内容之后的一个完整的server.xml配置文件(Tomcat版本为8.0)</p> <p><br></p> <p><br></p> <p><img data-ratio="0.7098484848484848" src="/upload/f60bd82aa3aa9d568996fec9b78bdf97.png" data-type="png" data-w="1320"></p> <p><span style="color: rgb(77, 77, 77);font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;font-size: 16px;font-variant-ligatures: common-ligatures;text-align: start;background-color: rgb(255, 255, 255);">详细的配置文件内容可以到Tomcat官网查看:</span></p> <p><span style="color: rgb(77, 77, 77);font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;font-size: 16px;font-variant-ligatures: common-ligatures;text-align: start;background-color: rgb(255, 255, 255);">http://tomcat.apache.org/tomcat-8.0-doc/index.html</span></p> <p><span style="color: rgb(77, 77, 77);font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;font-size: 16px;font-variant-ligatures: common-ligatures;text-align: start;background-color: rgb(255, 255, 255);"><span style="color: rgb(77, 77, 77);font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;font-size: 16px;font-variant-ligatures: common-ligatures;text-align: start;background-color: rgb(255, 255, 255);">上边的配置文件,还可以通过下边的一张结构图更清楚的理解:</span></span></p> <p><span style="color: rgb(77, 77, 77);font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;font-size: 16px;font-variant-ligatures: common-ligatures;text-align: start;background-color: rgb(255, 255, 255);"><img data-ratio="0.46017699115044247" src="/upload/861e161009e2589cfefaae73cf7c54d1.png" data-type="png" data-w="791"></span></p> <p>Server标签设置的端口号为8005,shutdown=”SHUTDOWN” ,表示在8005端口监听“SHUTDOWN”命令,如果接收到了就会关闭Tomcat。一个Server有一个Service,当然还可以进行配置,一个Service有多个Connector,Service左边的内容都属于Container的,Service下边是Connector。</p> <p><br></p> <p><strong><span style="font-size: 24px;">Tomcat顶层架构小结</span></strong></p> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p>Tomcat中只有一个Server,一个Server可以有多个Service,一个Service可以有多个Connector和一个Container;</p></li> <li><p>Server掌管着整个Tomcat的生死大权;</p></li> <li><p>Service 是对外提供服务的;</p></li> <li><p>Connector用于接受请求并将请求封装成Request和Response来具体处理;</p></li> <li><p>Container用于封装和管理Servlet,以及具体处理request请求;</p></li> </ul> <p><br></p> <p>知道了整个Tomcat顶层的分层架构和各个组件之间的关系以及作用,对于绝大多数的开发人员来说Server和Service对我们来说确实很远,而我们开发中绝大部分进行配置的内容是属于Connector和Container的,所以接下来介绍一下Connector和Container。</p> <p><br></p> <p><br></p> <h2 style="box-sizing: border-box;outline: 0px;margin-top: 8px;margin-bottom: 16px;font-size: 24px;font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;color: rgb(79, 79, 79);font-weight: 700;line-height: 32px;overflow-wrap: break-word;font-variant-ligatures: common-ligatures;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">Connector和Container的微妙关系</h2> <p>由上述内容我们大致可以知道一个请求发送到Tomcat之后,首先经过Service然后会交给我们的Connector,Connector用于接收请求并将接收的请求封装为Request和Response来具体处理,Request和Response封装完之后再交由Container进行处理,Container处理完请求之后再返回给Connector,最后在由Connector通过Socket将处理的结果返回给客户端,这样整个请求的就处理完了!</p> <p><br></p> <p>Connector最底层使用的是Socket来进行连接的,Request和Response是按照HTTP协议来封装的,所以Connector同时需要实现TCP/IP协议和HTTP协议!</p> <p><br></p> <p>Tomcat既然需要处理请求,那么肯定需要先接收到这个请求,接收请求这个东西我们首先就需要看一下Connector!</p> <p><br></p> <p><strong>Connector架构分析</strong></p> <p><br></p> <p>Connector用于接受请求并将请求封装成Request和Response,然后交给Container进行处理,Container处理完之后在交给Connector返回给客户端。</p> <p><br></p> <p>因此,我们可以把Connector分为四个方面进行理解:</p> <p><br></p> <ol class="list-paddingleft-2" style="list-style-type: decimal;"> <li><p>Connector如何接受请求的?</p><p><br></p></li> <li><p>如何将请求封装成Request和Response的?</p><p><br></p></li> <li><p>封装完之后的Request和Response如何交给Container进行处理的?</p><p><br></p></li> <li><p>Container处理完之后如何交给Connector并返回给客户端的?</p></li> </ol> <p><br></p> <p>首先看一下Connector的结构图(图B),如下所示:</p> <p><img data-ratio="0.47914032869785084" src="/upload/1809f3d102ef498acb029f68c5a1613e.png" data-type="png" data-w="791"></p> <p>Connector就是使用ProtocolHandler来处理请求的,不同的ProtocolHandler代表不同的连接类型,比如:Http11Protocol使用的是普通Socket来连接的,Http11NioProtocol使用的是NioSocket来连接的。</p> <p><br></p> <p>其中ProtocolHandler由包含了三个部件:Endpoint、Processor、Adapter。</p> <ol class="list-paddingleft-2" style="list-style-type: decimal;"> <li><p>Endpoint用来处理底层Socket的网络连接,Processor用于将Endpoint接收到的Socket封装成Request,Adapter用于将Request交给Container进行具体的处理。</p><p><br></p></li> <li><p>Endpoint由于是处理底层的Socket网络连接,因此Endpoint是用来实现TCP/IP协议的,而Processor用来实现HTTP协议的,Adapter将请求适配到Servlet容器进行具体的处理。</p><p><br></p></li> <li><p>Endpoint的抽象实现AbstractEndpoint里面定义的Acceptor和AsyncTimeout两个内部类和一个Handler接口。Acceptor用于监听请求,AsyncTimeout用于检查异步Request的超时,Handler用于处理接收到的Socket,在内部调用Processor进行处理。</p></li> </ol> <p><span style="color: rgb(77, 77, 77);font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;font-size: 16px;font-variant-ligatures: common-ligatures;text-align: start;background-color: rgb(255, 255, 255);">至此,我们应该很轻松的回答1,2,3的问题了,但是4还是不知道,那么我们就来看一下Container是如何进行处理的以及处理完之后是如何将处理完的结果返回给Connector的?</span></p> <p><br></p> <p><br></p> <h2 style="box-sizing: border-box;outline: 0px;margin-top: 8px;margin-bottom: 16px;font-size: 24px;font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;color: rgb(79, 79, 79);font-weight: 700;line-height: 32px;overflow-wrap: break-word;font-variant-ligatures: common-ligatures;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">Container架构分析</h2> <p style="box-sizing: border-box;outline: 0px;margin-bottom: 16px;font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;font-size: 16px;color: rgb(77, 77, 77);line-height: 26px;overflow-wrap: break-word;font-variant-ligatures: common-ligatures;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">Container用于封装和管理Servlet,以及具体处理Request请求,在Container内部包含了4个子容器,结构图如下(图C):</p> <p><img data-ratio="0.6162927981109799" src="/upload/9eac79bc5b52a60618a29d4c73ccf8c1.png" data-type="png" data-w="847"></p> <p>4个子容器的作用分别是:</p> <p><br></p> <ol class="list-paddingleft-2" style="list-style-type: decimal;"> <li><p>Engine:引擎,用来管理多个站点,一个Service最多只能有一个Engine;</p><p><br></p></li> <li><p>Host:代表一个站点,也可以叫虚拟主机,通过配置Host就可以添加站点;</p><p><br></p></li> <li><p>Context:代表一个应用程序,对应着平时开发的一套程序,或者一个WEB-INF目录以及下面的web.xml文件;</p><p><br></p></li> <li><p>Wrapper:每一Wrapper封装着一个Servlet;</p></li> </ol> <p><br></p> <p>下面找一个Tomcat的文件目录对照一下,如下图所示:</p> <p><img data-ratio="1.0449438202247192" src="/upload/a950b16d06877475df3ee9775c63f203.png" data-type="png" data-w="356"></p> <p>Context和Host的区别是Context表示一个应用,我们的Tomcat中默认的配置下webapps下的每一个文件夹目录都是一个Context,其中ROOT目录中存放着主应用,其他目录存放着子应用,而整个webapps就是一个Host站点。</p> <p><br></p> <p>我们访问应用Context的时候,如果是ROOT下的则直接使用域名就可以访问,例如:www.baidu.com,如果是Host(webapps)下的其他应用,则可以使用www.baidu.com/docs进行访问,当然默认指定的根应用(ROOT)是可以进行设定的,只不过Host站点下默认的主应用是ROOT目录下的。</p> <p>面试专场:<br></p> <p style="color: rgb(154, 154, 154);font-size: 15px;white-space: normal;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzUxNDA1NDI3OA==&amp;mid=2247486246&amp;idx=1&amp;sn=c9c670ce5d4e17d156bcc9e309efde98&amp;chksm=f94a8acfce3d03d97a6dce52a86d9898dcfd8c25309e6121fa4b2aa6a9c4c8079c29e4099a70&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">Redis面试题(2020最新版)</a><br></p> <p style="color: rgb(154, 154, 154);font-size: 15px;white-space: normal;"><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzUxNDA1NDI3OA==&amp;mid=2247486238&amp;idx=1&amp;sn=36f69624d21ffa6ef4815faabafbe9af&amp;chksm=f94a8af7ce3d03e1bf469aaf880e0dc55a5b4989657efc0b13fd9533875bd29ccbfdff703eec&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">消息中间件MQ与RabbitMQ面试题(2020最新版)</a></p> <p>看到这里我们知道Container是什么,但是还是不知道Container是如何进行请求处理的以及处理完之后是如何将处理完的结果返回给Connector的?别急!下边就开始探讨一下Container是如何进行处理的!</p> <h3 style="box-sizing: border-box;outline: 0px;margin-top: 8px;margin-bottom: 16px;font-size: 22px;font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;color: rgb(79, 79, 79);font-weight: 700;line-height: 30px;overflow-wrap: break-word;font-variant-ligatures: common-ligatures;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">Container如何处理请求的</h3> <p>Container处理请求是使用Pipeline-Valve管道来处理的!(Valve是阀门之意)</p> <p><br></p> <p>Pipeline-Valve是责任链模式,责任链模式是指在一个请求处理的过程中有很多处理者依次对请求进行处理,每个处理者负责做自己相应的处理,处理完之后将处理后的结果返回,再让下一个处理者继续处理。</p> <p><img data-ratio="0.3669609079445145" src="/upload/8099214c83f55933719f89bea9da9482.png" data-type="png" data-w="793"></p> <p>但是!Pipeline-Valve使用的责任链模式和普通的责任链模式有些不同!区别主要有以下两点:</p> <p><br></p> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p>每个Pipeline都有特定的Valve,而且是在管道的最后一个执行,这个Valve叫做BaseValve,BaseValve是不可删除的;</p><p><br></p></li> <li><p>在上层容器的管道的BaseValve中会调用下层容器的管道。</p></li> </ul> <p><br></p> <p>我们知道Container包含四个子容器,而这四个子容器对应的BaseValve分别在:StandardEngineValve、StandardHostValve、StandardContextValve、StandardWrapperValve。</p> <p><br></p> <p>Pipeline的处理流程图如下(图D):</p> <p><img data-ratio="0.7227848101265822" src="/upload/23443f92ab52cdbcc85cf44ad700103e.png" data-type="png" data-w="790"></p> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p>Connector在接收到请求后会首先调用最顶层容器的Pipeline来处理,这里的最顶层容器的Pipeline就是EnginePipeline(Engine的管道);</p><p><br></p></li> <li><p>在Engine的管道中依次会执行EngineValve1、EngineValve2等等,最后会执行StandardEngineValve,在StandardEngineValve中会调用Host管道,然后再依次执行Host的HostValve1、HostValve2等,最后在执行StandardHostValve,然后再依次调用Context的管道和Wrapper的管道,最后执行到StandardWrapperValve。</p><p><br></p></li> <li><p>当执行到StandardWrapperValve的时候,会在StandardWrapperValve中创建FilterChain,并调用其doFilter方法来处理请求,这个FilterChain包含着我们配置的与请求相匹配的Filter和Servlet,其doFilter方法会依次调用所有的Filter的doFilter方法和Servlet的service方法,这样请求就得到了处理!</p><p><br></p></li> <li><p>当所有的Pipeline-Valve都执行完之后,并且处理完了具体的请求,这个时候就可以将返回的结果交给Connector了,Connector在通过Socket的方式将结果返回给客户端。</p></li> </ul> <h2 style="box-sizing: border-box;outline: 0px;margin-top: 8px;margin-bottom: 16px;font-size: 24px;font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;color: rgb(79, 79, 79);font-weight: 700;line-height: 32px;overflow-wrap: break-word;font-variant-ligatures: common-ligatures;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">总结</h2> <p style="box-sizing: border-box;outline: 0px;margin-bottom: 16px;font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;font-size: 16px;color: rgb(77, 77, 77);line-height: 26px;overflow-wrap: break-word;font-variant-ligatures: common-ligatures;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);">至此,我们已经对Tomcat的整体架构有了大致的了解,从图A、B、C、D可以看出来每一个组件的基本要素和作用。我们在脑海里应该有一个大概的轮廓了!如果你面试的时候,让你简单的聊一下Tomcat,上面的内容你能脱口而出吗?当你能够脱口而出的时候,面试官一定会对你刮目相看的!</p> <p style="box-sizing: border-box;outline: 0px;margin-bottom: 16px;font-family: &quot;Microsoft YaHei&quot;, &quot;SF Pro Display&quot;, Roboto, Noto, Arial, &quot;PingFang SC&quot;, sans-serif;font-size: 16px;color: rgb(77, 77, 77);line-height: 26px;overflow-wrap: break-word;font-variant-ligatures: common-ligatures;text-align: start;white-space: normal;background-color: rgb(255, 255, 255);"><strong>面试专场:</strong></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzUxNDA1NDI3OA==&amp;mid=2247486246&amp;idx=1&amp;sn=c9c670ce5d4e17d156bcc9e309efde98&amp;chksm=f94a8acfce3d03d97a6dce52a86d9898dcfd8c25309e6121fa4b2aa6a9c4c8079c29e4099a70&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2"></a></p> <blockquote class="js_blockquote_wrap" data-type="2" data-url="" data-author-name="" data-content-utf8-length="268" data-source-title=""> <section class="js_blockquote_digest"> <section> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzUxNDA1NDI3OA==&amp;mid=2247486246&amp;idx=1&amp;sn=c9c670ce5d4e17d156bcc9e309efde98&amp;chksm=f94a8acfce3d03d97a6dce52a86d9898dcfd8c25309e6121fa4b2aa6a9c4c8079c29e4099a70&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">Redis面试题(2020最新版)</a><br></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzUxNDA1NDI3OA==&amp;mid=2247486238&amp;idx=1&amp;sn=36f69624d21ffa6ef4815faabafbe9af&amp;chksm=f94a8af7ce3d03e1bf469aaf880e0dc55a5b4989657efc0b13fd9533875bd29ccbfdff703eec&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">消息中间件MQ与RabbitMQ面试题(2020最新版)</a></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzUxNDA1NDI3OA==&amp;mid=2247486233&amp;idx=1&amp;sn=f1b4fa8bc476e44ee86827157c32120c&amp;chksm=f94a8af0ce3d03e689ed25cc7cb55aa2ba0cc7bcfb2bcd148fa347c5849744842cf344d2f89c&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">Spring Cloud面试题(2020最新版)</a></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzUxNDA1NDI3OA==&amp;mid=2247486222&amp;idx=1&amp;sn=fede2c994146afc17314df8e9699ee98&amp;chksm=f94a8ae7ce3d03f1faecafa0a6d5b481997a29a91496bd8ca54fa9afd88f5c7117636ac506a6&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">Java经典面试题整理及答案详解(一)</a><br></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzUxNDA1NDI3OA==&amp;mid=2247486211&amp;idx=1&amp;sn=28b470281c083d7453f08b1c3377b83f&amp;chksm=f94a8aeace3d03fcf3ffefa2eca67ff4b4f9cd426b7b4ba547c03863b7b0712e1f20896abfd0&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">面试官问:为什么需要消息队列?使用消息队列有什么好处?</a><br></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzUxNDA1NDI3OA==&amp;mid=2247486207&amp;idx=1&amp;sn=7cf36dabd34c38db80b10f3b2682bb12&amp;chksm=f94a8b16ce3d0200a8c10666b1f4ef05db230f7860087a24170b168f2c0960cb078b8744d574&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">Zookeeper超详细的面试题</a></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzUxNDA1NDI3OA==&amp;mid=2247486199&amp;idx=1&amp;sn=f1bc2ab5a19bd8ec1212c7ebe20e49ce&amp;chksm=f94a8b1ece3d02086129c6b22aac23dbe057372c6d30cb67f74d0627f8965ccc82a6be21bfbb&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">BAT大厂招聘</a><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzUxNDA1NDI3OA==&amp;mid=2247486199&amp;idx=1&amp;sn=f1bc2ab5a19bd8ec1212c7ebe20e49ce&amp;chksm=f94a8b1ece3d02086129c6b22aac23dbe057372c6d30cb67f74d0627f8965ccc82a6be21bfbb&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">Java 程序员的技术标准,你达到要求了吗?</a></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzUxNDA1NDI3OA==&amp;mid=2247486181&amp;idx=1&amp;sn=4acb70a48682cb18a3511d56944e956e&amp;chksm=f94a8b0cce3d021ad1b7b6bcc7564eb7a3d17f77b298493a5abb6ad43899413d570a5c8b84ae&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">别再说你不会分布式了,面试官能问的都在这了</a><br></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzUxNDA1NDI3OA==&amp;mid=2247486171&amp;idx=1&amp;sn=57c3feef86b0c7d5d049032c82eb2ed5&amp;chksm=f94a8b32ce3d02248d797fa781fab04a8baa4d881415bfd88088f650cdb7b24204142ccf0154&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">Spring MVC 面经</a><br></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzUxNDA1NDI3OA==&amp;mid=2247486156&amp;idx=1&amp;sn=53dd58336d7b717269f45c2448622dd5&amp;chksm=f94a8b25ce3d0233f595530ed447cd2980e72aadb84b1c20d129f055e8f37b2f502df9138b48&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">Java面试----2018年MyBatis常见实用面试题整理</a><br></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzUxNDA1NDI3OA==&amp;mid=2247486152&amp;idx=1&amp;sn=013cfb8e231aeb73fc214f96b06b02d4&amp;chksm=f94a8b21ce3d0237e9912f63c422d0725d6af3b7ac38cad28489406e273fc6deeb802ce9a9df&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">《图解HTTP》面试知道这些就差不多了!</a><br></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzUxNDA1NDI3OA==&amp;mid=2247486096&amp;idx=1&amp;sn=8a471403c996fb61b05bd631970d2e1b&amp;chksm=f94a8b79ce3d026f881d382996db1a6875c1b6895dd12129c9091e690612c14611a56e69518b&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">Spring经典面试题总结</a><br></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzUxNDA1NDI3OA==&amp;mid=2247486083&amp;idx=1&amp;sn=b431e6e522fe202279b24ae80ddfdcff&amp;chksm=f94a8b6ace3d027c5a5b21c7bce84ef879307f0e30f4b6398a3936b2e64f48fd569ed17b05ff&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2">面试:史上最全多线程面试题 !</a></p> </section> </section> </blockquote> <p><img src="/upload/dc8e3642ddbd4929ec2f7ede5eacac04.png" data-type="png" data-ratio="0.4875207986688852" data-w="601"></p> <p><a target="_blank" href="http://mp.weixin.qq.com/s?__biz=MzUxNDA1NDI3OA==&amp;mid=2247486083&amp;idx=1&amp;sn=b431e6e522fe202279b24ae80ddfdcff&amp;chksm=f94a8b6ace3d027c5a5b21c7bce84ef879307f0e30f4b6398a3936b2e64f48fd569ed17b05ff&amp;scene=21#wechat_redirect" data-itemshowtype="0" tab="innerlink" data-linktype="2"></a><br></p> <p><br></p>

你再不知道分布式事务,我就真的生气了!

作者:微信小助手

<section style="box-sizing: border-box;font-size: 16px;"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;" powered-by="xiumi.us"> <section style="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;">最近看了几篇有关于分布式事务的博文,做了一下笔记,并总结出这篇文章。</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> <section style="text-align: center;margin-left: 8px;margin-right: 8px;"> <img class="rich_pages" data-ratio="0.6669381107491856" data-s="300,640" src="/upload/b20dd00e61cc8ed37a21b12c8f70475f.jpg" data-type="jpeg" data-w="1228" style=""> </section> <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> <p style="text-align: center;margin-left: 8px;margin-right: 8px;margin-bottom: 5px;"><img class="rich_pages" data-ratio="0.42653606411398043" data-s="300,640" src="/upload/e05bc8c810f7efeafa0326e28e0ddc58.png" data-type="png" data-w="1123" style=""></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> <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;">这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。</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;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;">原子性(Atomicity)</span></strong></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">一致性(Consistency)</span></strong></p></li> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">隔离性(Isolation)</span></strong></p></li> <li> <section style="margin-bottom: 5px;"> <strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">持久性(Durabilily)</span></strong> </section></li> </ul> <p style="text-align: center;margin-bottom: 5px;margin-left: 8px;margin-right: 8px;"><img class="rich_pages" data-ratio="0.744408945686901" data-s="300,640" src="/upload/69c8c8576da3c1b4213cb4c0cbe311c1.png" data-type="png" data-w="626" style=""></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">简称就是 ACID:</span></p> <ul class="list-paddingleft-2" style="list-style-type: disc;"> <li><p><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">原子性:</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

Spring Boot 服务监控,健康检查,线程信息,JVM堆信息,指标收集,运行情况监控等!

作者:微信小助手

<p data-mpa-powered-by="yiban.io" style="white-space: normal;font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);text-align: center;"><strong style="letter-spacing: 0.544px;color: rgba(0, 0, 0, 0.498);font-size: 15px;widows: 1;"><span style="font-size: 14px;color: rgb(136, 136, 136);">点击上方“JavaGuide</span></strong><strong style="letter-spacing: 0.544px;color: rgba(0, 0, 0, 0.498);font-size: 15px;widows: 1;"><span style="font-size: 14px;color: rgb(136, 136, 136);">”,选择<strong style="color: rgba(0, 0, 0, 0.498);font-size: 15px;letter-spacing: 0.544px;">“</strong><span style="font-size: 15px;letter-spacing: 0.544px;color: rgb(120, 172, 254);"><strong><span style="font-size: 14px;">星标</span></strong></span><strong style="color: rgba(0, 0, 0, 0.498);font-size: 15px;letter-spacing: 0.544px;">”</strong></span></strong></p> <p data-darkmode-color="rgb(230, 230, 230)" data-style="white-space: normal; color: rgb(0, 0, 0); font-family: PingFangSC-Light; font-size: 16px; text-align: center;" class="js_darkmode__2" style="white-space: normal;text-align: center;"><strong style="letter-spacing: 0.544px;color: rgba(0, 0, 0, 0.498);font-size: 15px;widows: 1;"><span style="font-size: 14px;color: rgb(136, 136, 136);">回复”</span></strong><strong style="letter-spacing: 0.544px;color: rgba(0, 0, 0, 0.498);font-size: 15px;widows: 1;"><span style="font-size: 14px;color: rgb(136, 136, 136);"><span style="font-size: 15px;letter-spacing: 0.544px;color: rgb(120, 172, 254);"><strong><span style="letter-spacing: 0.544px;font-size: 14px;">面试突击</span></strong></span></span></strong><strong style="letter-spacing: 0.544px;color: rgba(0, 0, 0, 0.498);font-size: 15px;widows: 1;"><span style="font-size: 14px;color: rgb(136, 136, 136);">“获取Github 68k+ Star项目精华集合而成的《Java面试突击》</span></strong></p> <p style="font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);color: rgb(62, 62, 62);font-size: 15px;text-align: center;"><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.null" style="font-family: -apple-system-font, BlinkMacSystemFont, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;letter-spacing: 0.544px;widows: 1;word-spacing: 2px;color: rgb(136, 136, 136);font-size: 14px;visibility: visible !important;width: 654px !important;"></p> <section data-mpa-template="t" mpa-paragraph-type="ignored" style=""> <section style="margin-top: 10px;margin-bottom: 5px;max-width: 100%;letter-spacing: 0.544px;color: rgb(62, 62, 62);font-size: 15px;text-align: left;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <span style="max-width: 100%;font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;white-space: pre-line;font-size: 12px;color: rgb(178, 178, 178);box-sizing: border-box !important;overflow-wrap: break-word !important;">作者 |&nbsp;Richard_Yi</span> </section> <section style="margin-top: 5px;margin-bottom: 10px;max-width: 100%;letter-spacing: 0.544px;color: rgb(62, 62, 62);font-size: 15px;text-align: left;box-sizing: border-box !important;overflow-wrap: break-word !important;"> <span style="max-width: 100%;color: rgb(178, 178, 178);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;font-size: 12px;white-space: pre-line;letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;">来源 | </span> <span style="max-width: 100%;color: rgb(178, 178, 178);font-size: 10px;white-space: pre-line;letter-spacing: 0.544px;text-align: right;box-sizing: border-box !important;overflow-wrap: break-word !important;">rrd.me/fJVL7</span> </section> </section> <section data-role="outer" label="Powered by 135editor.com"> <p style="margin-top: 15px;margin-bottom: 15px;font-size: 14px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;text-align: start;">去年我们项目做了微服务1.0的架构转型,但是服务监控这块却没有跟上。这不,最近我就被分配了要将我们核心的微服务应用全部监控起来的任务。我们的微服务应用都是SpringBoot 应用,因此就自然而然的想到了借助Spring Boot 的Actuator 模块。</p> <p style="margin-top: 15px;margin-bottom: 15px;font-size: 14px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;text-align: start;">本篇是我在完成这个工单之后,对Spring Boot Actuator模块 学习应用的总结。在本篇文章中,你可以学习到:</p> <p style="margin-top: 15px;margin-bottom: 15px;font-size: 14px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;text-align: start;"><strong style="color: rgb(0, 0, 0);">1、</strong>Spring Boot Actuator 的快速使用入门<br><strong style="color: rgb(0, 0, 0);">2、</strong>Spring Boot Actuator 的一些重要的endpoints的介绍<br><strong style="color: rgb(0, 0, 0);">3、</strong>如何通过Actuator 模块实时查看当前应用的线程 dump信息<br><strong style="color: rgb(0, 0, 0);">4、</strong>如何通过Actuator 模块实时查看当前应用的堆信息<br><strong style="color: rgb(0, 0, 0);">5、</strong>如何通过Actuator 模块实时修改当前应用的日志打印等级<br><strong style="font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;font-size: 14px;text-align: start;white-space: pre-line;color: rgb(0, 0, 0);">6、</strong>...</p> <p style="margin-top: 15px;margin-bottom: 15px;font-size: 14px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;text-align: start;">之后我还会介绍:</p> <p><span style="color: rgb(74, 74, 74);line-height: 22px;font-size: 14px;">TODO:SpringBoot 微服务应用集成Prometheus + Grafana实现监控告警</span></p> <h2 style="margin-top: 1.5rem;margin-bottom: 1rem;color: rgb(255, 41, 65);line-height: 1.35;font-size: 17px;text-align: start;white-space: normal;font-family: Menlo, Monaco, &quot;Source Code Pro&quot;, Consolas, Inconsolata, &quot;Ubuntu Mono&quot;, &quot;DejaVu Sans Mono&quot;, &quot;Courier New&quot;, &quot;Droid Sans Mono&quot;, &quot;Hiragino Sans GB&quot;, 微软雅黑, monospace !important;"><span style="color: rgb(61, 167, 66);"><strong>一、什么是 Spring Boot Actuator</strong></span></h2> <p style="margin-top: 15px;margin-bottom: 15px;font-size: 14px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;text-align: start;">Spring Boot Actuator 模块提供了生产级别的功能,比如健康检查,审计,指标收集,HTTP 跟踪等,帮助我们监控和管理Spring Boot 应用、Bean加载情况、环境变量、日志信息、线程信息,JVM 堆信息等&nbsp;。这个模块是一个采集应用内部信息暴露给外部的模块,上述的功能都可以通过HTTP 和 JMX 访问。</p> <p style="margin-top: 15px;margin-bottom: 15px;font-size: 14px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;text-align: start;">因为暴露内部信息的特性,Actuator 也可以和一些外部的应用监控系统整合(Prometheus, Graphite, DataDog, Influx, Wavefront, New Relic等)。这些监控系统提供了出色的仪表板,图形,分析和警报,可帮助你通过一个统一友好的界面,监视和管理你的应用程序。</p> <p style="margin-top: 15px;margin-bottom: 15px;font-size: 14px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;text-align: start;">Actuator使用Micrometer与这些外部应用程序监视系统集成。这样一来,只需很少的配置即可轻松集成外部的监控系统。</p> <blockquote style="margin-bottom: 1.2em;padding: 15px 15px 15px 1rem;color: rgb(129, 145, 152);border-left-width: 6px;border-left-color: rgb(220, 230, 240);font-size: 14px;line-height: 22px;background: rgb(242, 247, 251);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;text-align: start;white-space: normal;"> <p style="margin-bottom: 15px;white-space: pre-line;line-height:

python mysqlclient-1.4.6-cp38-cp38-win32.whl is not a supported wheel on this platform.

作者:じ☆ve不哭

> pip install mysqlclient, mysqlclient-1.4.6-cp38-cp38-win32.whl is not a supported wheel on this platform. python安装mysqlclient的时候提示如上错误。 ## 查看python的安装版本 ``` 直接cmd输入python 或者在python控制台输入如下内容 import sys; print('Python %s on %s' % (sys.version, sys.platform)) ``` ![1583822843(1).png](/storage/thumbnails/_signature/36TAQ7Q05I3RF4A2MK52UGUD93.png) python 3.8 64bit ## 去下载whl的MySQLclient安装包 [https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient](https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient) ![1583822989(1).png](/storage/thumbnails/_signature/222M8MUONM86HBF2JE5MATH75T.png) ## 通过pip安装whl ``` pip install C:\Users\zsljava\Desktop\mysqlclient-1.4.6-cp38-cp38-win_amd64.whl ``` 提示错误:mysqlclient-1.4.6-cp38-cp38-win32.whl is not a supported wheel on this platform. ![1583823046(1).png](/storage/thumbnails/_signature/2IIE0JSAI1SHUSR3T9HAFIHPAM.png) ## 解决问题 - 1、 确认MySQLclient下载版本是否正确 python版本以及确认是32bit还是64bit - 2、 文件名错误 ``` # python控制台输入: import pip._internal; print(pip._internal.pep425tags.get_supported()) ``` ![1583823222(1).png](/storage/thumbnails/_signature/16EJFQK8TF85J8F344TV1AQ56C.png) 通过第一个参数可知,将文件名修改为mysqlclient-1.4.6-cp38-cp38m-win_amd64.whl即可(或者mysqlclient-1.4.6-cp38-none-win_amd64.whl) ``` pip install C:\Users\zsljava\Desktop\mysqlclient-1.4.6-cp38-cp38m-win_amd64.whl ``` ![1583823366(1).png](/storage/thumbnails/_signature/2OA321390SAVTETFE7GBSAUATC.png)

狠人 Spring Cloud 20000 字总结!

作者:微信小助手

<section style="display: none;" data-tools="新媒体管家" data-label="powered by xmt.cn"> <br> </section> <section style="text-align: center;padding-left: 0.5em;padding-right: 0.5em;letter-spacing: 1.5px;"> <img class="rich_pages" data-ratio="0.9511173184357542" data-s="300,640" src="/upload/b700bda8a0a65791f673323c45df3f23.jpg" data-type="jpeg" data-w="716" style=""> </section> <section style="padding-left: 0.5em;padding-right: 0.5em;letter-spacing: 1.5px;"> <span style="font-size: 14px;color: rgb(136, 136, 136);">来源丨java思维导图</span> </section> <section style="padding-left: 0.5em;padding-right: 0.5em;letter-spacing: 1.5px;"> <span style="font-size: 14px;color: rgb(136, 136, 136);">juejin.im/post/5de2553e5188256e885f4fa3</span> </section> <hr style="border-style: solid;border-width: 1px 0px 0px;border-color: rgba(0, 0, 0, 0.1);transform-origin: 0px 0px 0px;transform: scale(1, 0.5);padding-left: 0.5em;padding-right: 0.5em;"> <section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="padding-left: 0.5em;padding-right: 0.5em;"> <section style="letter-spacing: 1.5px;"> <br> </section> <section style="letter-spacing: 1.5px;"> <span style="font-size: 16px;">首先我给大家看一张图,如果大家对这张图有些地方不太理解的话,我希望你们看完我这篇文章会恍然大悟。<br></span> </section> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;line-height: 1.6 !important;"><img data-ratio="0.56953125" src="/upload/eb3f51637132d16be1be0879f00a7de4.jpg" data-type="jpeg" data-w="1280" style="display: block;margin: 0px;width: 100%;line-height: 1.6 !important;top: auto;left: auto;right: auto;bottom: auto;"></p> <h1 data-tool="mdnice编辑器" style="font-weight: bold;margin-top: 1em;margin-bottom: 1em;font-size: 1.4em;padding-bottom: 0.3em;border-bottom: 1px solid rgb(223, 226, 229);letter-spacing: 1.5px;line-height: 1.6 !important;"><span style="font-size: 16px;line-height: 1.6 !important;">什么是Spring cloud</span></h1> <blockquote data-tool="mdnice编辑器" style="font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);margin-bottom: 20px;margin-top: 20px;background-image: none;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;border-left-width: 4px;border-left-color: rgb(221, 221, 221);padding-top: 0px;padding-right: 1em;padding-left: 1em;"> <section style="font-size: inherit;color: rgb(102, 102, 102);letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">构建分布式系统不需要复杂和容易出错。Spring Cloud 为最常见的分布式系统模式提供了一种简单且易于接受的编程模型,帮助开发人员构建有弹性的、可靠的、协调的应用程序。Spring Cloud 构建于 Spring Boot 之上,使得开发者很容易入手并快速应用于生产中。</span> </section> </blockquote> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">官方果然官方,介绍都这么有板有眼的。</span> </section> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">我所理解的 </span> <code style=""><span style="font-size: 16px;">Spring Cloud</span></code> <span style="font-size: 16px;"> 就是微服务系统架构的一站式解决方案,在平时我们构建微服务的过程中需要做如 <strong style="line-height: 1.6 !important;">服务发现注册</strong> 、<strong style="line-height: 1.6 !important;">配置中心</strong> 、<strong style="line-height: 1.6 !important;">消息总线</strong> 、<strong style="line-height: 1.6 !important;">负载均衡</strong> 、<strong style="line-height: 1.6 !important;">断路器</strong> 、<strong style="line-height: 1.6 !important;">数据监控</strong> 等操作,而 Spring Cloud 为我们提供了一套简易的编程模型,使我们能在 Spring Boot 的基础上轻松地实现微服务项目的构建。</span> </section> <h1 data-tool="mdnice编辑器" style="font-weight: bold;margin-top: 1em;margin-bottom: 1em;font-size: 1.4em;padding-bottom: 0.3em;border-bottom: 1px solid rgb(223, 226, 229);letter-spacing: 1.5px;line-height: 1.6 !important;"><span style="font-size: 16px;line-height: 1.6 !important;">Spring Cloud 的版本</span></h1> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">当然这个只是个题外话。</span> </section> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">Spring Cloud 的版本号并不是我们通常见的数字版本号,而是一些很奇怪的单词。这些单词均为英国伦敦地铁站的站名。同时根据字母表的顺序来对应版本时间顺序,比如:最早 的 Release 版本 Angel,第二个 Release 版本 Brixton(英国地名),然后是 Camden、 Dalston、Edgware、Finchley、Greenwich、Hoxton。</span> </section> <h1 data-tool="mdnice编辑器" style="font-weight: bold;margin-top: 1em;margin-bottom: 1em;font-size: 1.4em;padding-bottom: 0.3em;border-bottom: 1px solid rgb(223, 226, 229);letter-spacing: 1.5px;line-height: 1.6 !important;"><span style="font-size: 16px;line-height: 1.6 !important;">Spring Cloud 的服务发现框架——Eureka</span></h1> <blockquote data-tool="mdnice编辑器" style="font-size: 0.9em;overflow: auto;color: rgb(106, 115, 125);margin-bottom: 20px;margin-top: 20px;background-image: none;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;border-left-width: 4px;border-left-color: rgb(221, 221, 221);padding-top: 0px;padding-right: 1em;padding-left: 1em;"> <section style="font-size: inherit;color: rgb(102, 102, 102);letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">Eureka是基于REST(代表性状态转移)的服务,主要在AWS云中用于定位服务,以实现负载均衡和中间层服务器的故障转移。我们称此服务为Eureka服务器。Eureka还带有一个基于Java的客户端组件Eureka Client,它使与服务的交互变得更加容易。客户端还具有一个内置的负载平衡器,可以执行基本的循环负载平衡。在Netflix,更复杂的负载均衡器将Eureka包装起来,以基于流量,资源使用,错误条件等多种因素提供加权负载均衡,以提供出色的弹性。</span> </section> </blockquote> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">总的来说,Eureka 就是一个服务发现框架。何为服务,何又为发现呢?</span> </section> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">举一个生活中的例子,就比如我们平时租房子找中介的事情。</span> </section> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">在没有中介的时候我们需要一个一个去寻找是否有房屋要出租的房东,这显然会非常的费力,一你找凭一个人的能力是找不到很多房源供你选择,再者你也懒得这么找下去(找了这么久,没有合适的只能将就)。<strong style="line-height: 1.6 !important;">这里的我们就相当于微服务中的 </strong><strong style="line-height: 1.6 !important;"><code style="">Consumer</code> ,而那些房东就相当于微服务中的 <code style="">Provider</code> 。消费者 <code style="">Consumer</code> 需要调用提供者 <code style="">Provider</code> 提供的一些服务,就像我们现在需要租他们的房子一样。</strong></span> </section> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">但是如果只是租客和房东之间进行寻找的话,他们的效率是很低的,房东找不到租客赚不到钱,租客找不到房东住不了房。所以,后来房东肯定就想到了广播自己的房源信息(比如在街边贴贴小广告),这样对于房东来说已经完成他的任务(将房源公布出去),但是有两个问题就出现了。第一、其他不是租客的都能收到这种租房消息,这在现实世界没什么,但是在计算机的世界中就会出现<strong style="line-height: 1.6 !important;">资源消耗</strong> 的问题了。第二、租客这样还是很难找到你,试想一下我需要租房,我还需要东一个西一个地去找街边小广告,麻不麻烦?</span> </section> <section style="text-align: center;letter-spacing: 1.5px;"> <img class="rich_pages" data-ratio="1.125" data-s="300,640" src="/upload/c2767404f0a90cbdbf501c9a75d69eb6.png" data-type="png" data-w="400" style="width: 48%;height: auto !important;"> </section> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;text-align: left;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">那怎么办呢?我们当然不会那么傻乎乎的,第一时间就是去找 <strong style="font-size: inherit;line-height: 1.6 !important;">中介</strong> 呀,它为我们提供了统一房源的地方,我们消费者只需要跑到它那里去找就行了。而对于房东来说,他们也只需要把房源在中介那里发布就行了。</span> </section> <section style="text-align: center;letter-spacing: 1.5px;"> <img class="rich_pages" data-ratio="1" src="/upload/55e595a614c76cf5b6cc5f81758cd60.gif" data-type="gif" data-w="220" style=""> </section> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">那么现在,我们的模式就是这样的了。</span> </section> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;line-height: 1.6 !important;"><img data-ratio="0.4363295880149813" src="/upload/3614dd8e3957e7efcc831c988749b3.jpg" data-type="jpeg" data-w="1068" style="display: block;margin: 0px;width: 100%;line-height: 1.6 !important;top: auto;left: auto;right: auto;bottom: auto;"></p> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">但是,这个时候还会出现一些问题。</span> </section> <ol data-tool="mdnice编辑器" class="list-paddingleft-2"> <li style="font-size: 16px;"> <section style="color: rgb(1, 1, 1);margin-top: 0.3em;margin-bottom: 0.3em;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">房东注册之后如果不想卖房子了怎么办?我们是不是需要让房东<strong style="color: rgb(51, 51, 51);line-height: 1.6 !important;">定期续约</strong> ?如果房东不进行续约是不是要将他们从中介那里的注册列表中<strong style="color: rgb(51, 51, 51);line-height: 1.6 !important;">移除</strong> 。</span> </section></li> <li style="font-size: 16px;"> <section style="color: rgb(1, 1, 1);margin-top: 0.3em;margin-bottom: 0.3em;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">租客是不是也要进行<strong style="color: rgb(51, 51, 51);line-height: 1.6 !important;">注册</strong> 呢?不然合同乙方怎么来呢?</span> </section></li> <li style="font-size: 16px;"> <section style="color: rgb(1, 1, 1);margin-top: 0.3em;margin-bottom: 0.3em;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">中介可不可以做<strong style="color: rgb(51, 51, 51);line-height: 1.6 !important;">连锁店</strong> 呢?如果这一个店因为某些不可抗力因素而无法使用,那么我们是否可以换一个连锁店呢?</span> </section></li> </ol> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">针对上面的问题我们来重新构建一下上面的模式图</span> </section> <p data-tool="mdnice编辑器" style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;line-height: 1.6 !important;"><img data-ratio="0.5685936151855048" src="/upload/5bc2cae110ce0e84e83fa3326ccc5d51.jpg" data-type="jpeg" data-w="1159" style="display: block;margin: 0px;width: 100%;line-height: 1.6 !important;top: auto;left: auto;right: auto;bottom: auto;"></p> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">好了,举完这个🌰我们就可以来看关于 Eureka 的一些基础概念了,你会发现这东西理解起来怎么这么简单。👎👎👎</span> </section> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;"><strong style="line-height: 1.6 !important;">服务发现</strong> :其实就是一个“中介”,整个过程中有三个角色:<strong style="line-height: 1.6 !important;">服务提供者(出租房子的)、服务消费者(租客)、服务中介(房屋中介)</strong> 。</span> </section> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;"><strong style="line-height: 1.6 !important;">服务提供者</strong> :就是提供一些自己能够执行的一些服务给外界。</span> </section> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;"><strong style="line-height: 1.6 !important;">服务消费者</strong> :就是需要使用一些服务的“用户”。</span> </section> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;"><strong style="line-height: 1.6 !important;">服务中介</strong> :其实就是服务提供者和服务消费者之间的“桥梁”,服务提供者可以把自己注册到服务中介那里,而服务消费者如需要消费一些服务(使用一些功能)就可以在服务中介中寻找注册在服务中介的服务提供者。</span> </section> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;"><strong style="line-height: 1.6 !important;">服务注册 Register</strong> :</span> </section> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">官方解释:当 Eureka 客户端向 </span> <code style=""><span style="font-size: 16px;">[Eureka](https://mp.weixin.qq.com/s/etloMGMydBgC0Ll1yBgx8Q) Server</span></code> <span style="font-size: 16px;"> 注册时,它提供自身的<strong style="line-height: 1.6 !important;">元数据</strong> ,比如IP地址、端口,运行状况指示符URL,主页等。</span> </section> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">结合中介理解:房东 (提供者 </span> <code style=""><span style="font-size: 16px;">[Eureka](https://mp.weixin.qq.com/s/etloMGMydBgC0Ll1yBgx8Q) Client Provider</span></code> <span style="font-size: 16px;">)在中介 (服务器 </span> <code style=""><span style="font-size: 16px;">[Eureka](https://mp.weixin.qq.com/s/etloMGMydBgC0Ll1yBgx8Q) Server</span></code> <span style="font-size: 16px;">) 那里登记房屋的信息,比如面积,价格,地段等等(元数据 </span> <code style=""><span style="font-size: 16px;">metaData</span></code> <span style="font-size: 16px;">)。</span> </section> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;"><strong style="line-height: 1.6 !important;">服务续约 Renew</strong> :</span> </section> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">官方解释:<strong style="line-height: 1.6 !important;">Eureka 客户会每隔30秒(默认情况下)发送一次心跳来续约</strong> 。通过续约来告知 </span> <code style=""><span style="font-size: 16px;">[Eureka](https://mp.weixin.qq.com/s/etloMGMydBgC0Ll1yBgx8Q) Server</span></code> <span style="font-size: 16px;"> 该 Eureka 客户仍然存在,没有出现问题。正常情况下,如果 </span> <code style=""><span style="font-size: 16px;">[Eureka](https://mp.weixin.qq.com/s/etloMGMydBgC0Ll1yBgx8Q) Server</span></code> <span style="font-size: 16px;"> 在90秒没有收到 Eureka 客户的续约,它会将实例从其注册表中删除。</span> </section> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">结合中介理解:房东 (提供者 </span> <code style=""><span style="font-size: 16px;">[Eureka](https://mp.weixin.qq.com/s/etloMGMydBgC0Ll1yBgx8Q) Client Provider</span></code> <span style="font-size: 16px;">) 定期告诉中介 (服务器 </span> <code style=""><span style="font-size: 16px;">[Eureka](https://mp.weixin.qq.com/s/etloMGMydBgC0Ll1yBgx8Q) Server</span></code> <span style="font-size: 16px;">) 我的房子还租(续约) ,中介 (服务器</span> <code style=""><span style="font-size: 16px;">[Eureka](https://mp.weixin.qq.com/s/etloMGMydBgC0Ll1yBgx8Q) Server</span></code> <span style="font-size: 16px;">) 收到之后继续保留房屋的信息。</span> </section> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;"><strong style="line-height: 1.6 !important;">获取注册列表信息 Fetch Registries</strong> :</span> </section> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spacing: 1.5px;line-height: 1.6 !important;"> <span style="font-size: 16px;">官方解释:Eureka 客户端从服务器获取注册表信息,并将其缓存在本地。客户端会使用该信息查找其他服务,从而进行远程调用。该注册列表信息定期(每30秒钟)更新一次。每次返回注册列表信息可能与 Eureka 客户端的缓存信息不同, Eureka 客户端自动处理。如果由于某种原因导致注册列表信息不能及时匹配,Eureka 客户端则会重新获取整个注册表信息。Eureka 服务器缓存注册列表信息,整个注册表以及每个应用程序的信息进行了压缩,压缩内容和没有压缩的内容完全相同。Eureka 客户端和 Eureka 服务器可以使用JSON / XML格式进行通讯。在默认的情况下 Eureka 客户端使用压缩 </span> <code style=""><span style="font-size: 16px;">JSON</span></code> <span style="font-size: 16px;"> 格式来获取注册列表的信息。</span> </section> <section style="margin-top: 1em;margin-bottom: 1em;font-size: inherit;letter-spa