作者:微信小助手
<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com"> <h2 data-sourcepos="21:1-21:70" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top-width: 1px;border-top-style: solid;border-top-color: rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">来一个大的介绍:ElasticSearch的性能优化的几大方面</span></h2> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">总的来说,ElasticSearch的性能优化,可以从以下方面的考虑:</span> </section> <ul data-sourcepos="25:1-48:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">硬件层面的优化:</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">机器分配,机器配置,机器内存,机器CPU,机器网络,机器磁盘性能</span> </section></li> <li style="margin-top: 0.25em;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">系统层面的优化:</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">文件句柄优化、swap关闭</span> </section></li> <li style="margin-top: 0.25em;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">ElasticSearch集群层面的优化</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">合理分配节点,</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">合理分配参加竞选Master的节点</span> </section></li> <li style="margin-top: 0.25em;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">ElasticSearch 索引层面的优化,</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">副本数量、索引数量、分片数量</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">ElasticSearch查询层面的优化</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">7 职责分离,全面监控</span> </section></li> </ul> <h2 data-sourcepos="49:1-49:28" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top-width: 1px;border-top-style: solid;border-top-color: rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">1 硬件层面的优化</span></h2> <h3 data-sourcepos="53:1-53:51" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">1.1 为ES进行 硬件层面的 内存优化:</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">Elasticsearch是一个内存密集型应用,合理分配内存对于Elasticsearch 提高性能至关重要:</span> </section> <ul data-sourcepos="57:1-64:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">确保系统内存有足够的空间用于文件缓存,而不单单是JVM堆内存。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">建议将一半的内存分配给Elasticsearch的堆内存,另一半留给操作系统和其他进程。</span> </section></li> <li style="margin-top: 0.25em;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">为了避免垃圾回收(GC)成为瓶颈,建议设置堆内存的最大值为30GB或更小。可以通过修改</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">jvm.options</span></code> <span style="font-size: 15px;">文件来调整堆内存的大小。</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">总之,ES是比较依赖内存的,并且对内存的消耗也很大,内存对ES的重要性甚至是高于CPU的,所以即使是数据量不大的业务,为了保证服务的稳定性,在满足业务需求的前提下,我们仍需考虑留有不少于20%的冗余性能。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">根据业务量不同,内存的需求也不同,一般生产建议总体 32内存,其中JVM 不要少于16G, 还有 16G给底层的Luence。</span> </section> <h3 data-sourcepos="71:1-71:44" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">为ES进行 系统层面的 磁盘优化</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">对于ES来说,磁盘可能是最重要的了,因为数据都是存储在磁盘上的,当然这里说的磁盘指的是磁盘的性能。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">磁盘性能往往是硬件性能的瓶颈,木桶效应中的最短板。</span> </section> <h4 data-sourcepos="79:1-79:61" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">方式一:纵向扩展: 使用最高性能的 磁盘</span></h4> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">ES 磁盘优化的最为简单,最为粗暴的方式是 纵向扩展,就是使用最高性能的 磁盘,比如SSD 固态硬盘。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">ES应用可能要面临不间断的大量的数据读取和写入,数据规模非常庞大, 尼恩曾经架构过的一个30个节点ES集群,数据量非常庞大,达到1TB 。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">一般来说,速度最快的,也是最昂贵的。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">不可能都用SSD硬盘, 一般是 SSD和机械硬盘组合使用。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">所以,可以考虑把节点冷热分离:</span> </section> <ul data-sourcepos="93:1-100:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">“热节点”使用SSD做存储,可以大幅提高系统性能;</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">“冷数据“存储在机械硬盘中,降低成本。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">如果使用磁盘阵列,可以使用RAID 0。</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>这里,尼恩给大家来点基础知识, 什么是RAID 0?</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">RAID(Redundant Array of Independent Disks,独立磁盘冗余阵列)是一种将多个物理磁盘组合成一个逻辑单元的数据存储虚拟化技术,其目的是提高数据存储的性能、可靠性或两者兼顾。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">RAID 0 是RAID中一种配置方式,具体含义如下:</span> </section> <ol data-sourcepos="107:1-140:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;"><strong>RAID 0 定义</strong>:</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">RAID 0 又称为条带化(Striping),它将数据分散存储在两个或多个硬盘上,每个硬盘只存储数据的一部分,从而提高数据的读写速度。</span> </section></li> <li style="margin-top: 0.25em;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;"><strong>工作原理</strong>:</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">在RAID 0配置中,数据被分成多个块(称为“条带”),并按顺序存储在多个硬盘上。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">例如,如果有一个4KB的数据块,它会被分成4个1KB的块,分别存储在4个硬盘上。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">读取数据时,因为可以同时从多个硬盘读取,所以读取速度会加快。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">写入数据时也是同理,数据会被分成多个块并行写入多个硬盘。</span> </section></li> <li style="margin-top: 0.25em;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;"><strong>性能提升</strong>:</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">RAID 0 的主要优势在于提高数据的读写速度。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">由于数据被分散在多个硬盘上,所以理论上,RAID 0 的读写速度可以达到单个硬盘速度的总和。</span> </section></li> <li style="margin-top: 0.25em;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;"><strong>没有冗余</strong>:</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">RAID 0 的缺点是没有数据冗余。如果其中一个硬盘发生故障,整个阵列上的数据都会丢失,因为每个硬盘上只存储数据的一部分,没有副本。</span> </section></li> <li style="margin-top: 0.25em;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;"><strong>适用场景</strong>:</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">RAID 0 适用于对性能要求高而对数据安全性要求不高的场景,如视频编辑、大型数据库的临时存储等。</span> </section></li> <li style="margin-top: 0.25em;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;"><strong>RAID 0 风险</strong>:</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">由于没有数据冗余,RAID 0 的风险较高。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">一旦硬盘发生故障,整个RAID 0 阵列上的数据都会丢失,因此在使用RAID 0 时需要非常小心,并且定期备份数据。</span> </section></li> </ol> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">总结来说,RAID 0 是一种通过将数据分散存储在多个硬盘上来提高性能的配置方式,但它不提供任何数据冗余,因此使用时需要考虑到数据丢失的风险。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>这里,尼恩给大家再来点基础知识, 看看 RAID 0 和 RAID 1 的区别?</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">RAID 0 和 RAID 1 是两种不同的RAID配置,RAID 0 和 RAID 1 在数据存储、性能和可靠性方面有显著的区别:</span> </section> <ol data-sourcepos="147:1-166:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;"><strong>RAID 0(条带化)</strong>: 多块磁盘并行读写</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;"><strong>数据存储</strong>:数据被分割成多个块(条带),然后分散存储在两个或多个硬盘上。这意味着每个硬盘上存储的是数据的不同部分,而不是数据的副本。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;"><strong>性能</strong>:由于数据的读写操作可以并行进行,RAID 0 可以提供很高的数据传输速率,特别是在写入大量数据时。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;"><strong>可靠性</strong>:RAID 0 没有数据冗余,任何一个硬盘的故障都会导致整个阵列上的数据丢失。因此,RAID 0 的可靠性最低。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;"><strong>适用场景</strong>:适合对读写性能要求高、对数据安全性要求不高的应用,如视频处理、大型数据库的临时存储等。</span> </section></li> <li style="margin-top: 0.25em;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;"><strong>RAID 1(镜像)</strong>: 多块磁盘冗写,并行读</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;"><strong>数据存储</strong>:数据在两个硬盘上存储完全相同的副本,即镜像。这意味着数据在两个硬盘上都有备份。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;"><strong>性能</strong>:RAID 1 的读取性能通常比写入性能要好,因为多个硬盘可以同时读取数据。但是,写入性能可能受到限制,因为数据需要同时写入两个硬盘。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;"><strong>可靠性</strong>:RAID 1 提供了很好的数据冗余,即使一个硬盘发生故障,另一个硬盘上的数据副本仍然可以保证数据的完整性和可用性。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;"><strong>适用场景</strong>:适合对数据安全性要求高的应用,如关键业务数据存储、服务器操作系统等。</span> </section></li> </ol> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">总结来说,RAID 0 提供了高性能但牺牲了数据安全性,而RAID 1 则提供了数据冗余和较高的可靠性,但性能相对较低。在选择RAID配置时,需要根据具体的应用需求和预算来决定使用哪种RAID级别。</span> </section> <h4 data-sourcepos="171:1-171:72" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">方式二:横向扩展:使用多块硬盘提高 硬盘的性能</span></h4> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><br></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">横向 扩展,就是 搞多块磁盘。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">Elasticsearch 通过多个</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">path.data</span></code> <span style="font-size: 15px;">目录配置,把Elasticsearch数据条带化分配到使用多块硬盘上面,以提高I/O性能。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">要在Elasticsearch中使用多块硬盘,并通过配置多个</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">path.data</span></code> <span style="font-size: 15px;">目录来实现数据的条带化分配,可以按照以下步骤操作:</span> </section> <ol data-sourcepos="185:1-186:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;"><strong>配置多个数据路径</strong>:</span> </section></li> </ol> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在Elasticsearch的配置文件</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">elasticsearch.yml</span></code> <span style="font-size: 15px;">中,可以指定多个数据存储路径(对应到多个磁盘),用逗号分隔。 例如,如果你有三块硬盘,并且已经分别挂载在</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">/mnt/disk1</span></code> <span style="font-size: 15px;">、</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">/mnt/disk2</span></code> <span style="font-size: 15px;">和</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">/mnt/disk3</span></code> <span style="font-size: 15px;">,你可以这样配置:</span> </section> <pre data-sourcepos="191:4-193:6" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;"><span style="color: rgb(1, 86, 146);">path.data:</span> <span style="color: rgb(84, 121, 13);">/mnt/disk1,/mnt/disk2,/mnt/disk3</span><br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这样配置后,Elasticsearch会尝试在这些路径上存储数据,类似于软件层面的RAID 0配置。</span> </section> <ol start="2" data-sourcepos="197:1-198:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;"><strong>ES的分片分配机制</strong>:</span> </section></li> </ol> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">Elasticsearch在选择存储分片的路径时,会根据一定的逻辑来选择最佳路径。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">Elasticsearch会优先选择磁盘使用率较低(/最为空闲)的磁盘来存储新的分片数据文件。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">如果多个路径可用,Elasticsearch会根据剩余空间和已存储的分片数量来决定将分片分配到哪个路径上。</span> </section> <ol start="3" data-sourcepos="205:1-206:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;"><strong>数据安全性问题</strong>:</span> </section></li> </ol> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">虽然使用多个</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">path.data</span></code> <span style="font-size: 15px;">路径可以提高I/O性能,但这种做法类似于软件层面的RAID 0,没有在磁盘层面 做 数据冗余。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">如果其中一个硬盘发生故障,存储在该硬盘上的所有分片都会丢失。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">因此,官方建议,确保每个分片至少有一个副本分片,以防止数据丢失。</span> </section> <h4 data-sourcepos="215:1-215:45" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">系统层面的ES 磁盘优化 总结:</span></h4> <ul data-sourcepos="217:1-225:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">ES应用可能要面临不间断的大量的数据读取和写入,磁盘关系到 ES的性能,建议使用最高速的磁盘设备(如SSD)可以显著提高Elasticsearch的性能。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">当然最高速也是最昂贵的,不可能都用SSD硬盘, 一般是 SSD和机械硬盘组合使用。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">合理规划磁盘布局,可以考虑把节点冷热分离, 将数据按照冷热的程度,存储在不同的磁盘上,可以避免磁盘I/O竞争。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">使用RAID 0可以提高磁盘I/O,但要注意数据的安全性。</span> </section></li> <li style="margin-top: 0.25em;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">通过多个</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">path.data</span></code> <span style="font-size: 15px;">目录配置,把Elasticsearch数据条带化分配到使用多块硬盘上面,以提高I/O性能。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">避免使用远程挂载的存储,比如NFS或者SMB/CIFS,因为这会引入延迟,影响性能。</span> </section></li> </ul> <h3 data-sourcepos="226:1-226:47" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">1.2 为ES进行 硬件层面的 CPU 调优</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">CPU对其他的 应用程序而言,可谓是最重要的硬件,</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">但对于ES来说,CPU不是他最依赖的硬件, 提升CPU配置可能不会像提升磁盘或者内存配置带来的性能收益更直接、显著。在成本预算一定的前提下,应该把更多的预算花在磁盘以及内存上面。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">当然也不是说CPU的性能就不重要,Elasticsearch在处理查询和索引操作时会消耗大量的CPU资源。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">服务器的CPU不需要太高的单核性能,更多的核心数和线程数意味着更高的并发处理能力。现在PC的配置8核都已经普及了,更不用说服务器了。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">对于ES来说,通常来说单节点cpu 4核起步,不同角色的节点对CPU的要求也不同。</span> </section> <h4 data-sourcepos="240:1-240:77" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">CPU优化的第一步:角色分离,合理分配节点角色与资源</span></h4> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在 ElasticSearch 集群中,明确划分主节点(Master)、数据节点(Data)和协调节点(Coordinating)的角色。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">主节点(Master)主要负责集群的管理和元数据存储,其 CPU 负载主要来自于集群状态的维护和更新。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">数据节点(Data)负责存储和索引数据,在数据写入和查询操作时会占用较多 CPU 资源,这是CPU的大户。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">协调节点(Coordinating)负责接收用户查询请求并将其分发到合适的数据节点进行处理,也会消耗一定的 CPU 资源用于请求的转发和结果的合并。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,在一个大型的ES集群中,大致的CPU配置如下:</span> </section> <ul data-sourcepos="256:1-263:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">主节点(Master)配置在性能稳定、CPU 核心数适中(如 4 - 8 核)的服务器上,专门用于处理集群管理任务;</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">数据节点(Data)则根据数据量和查询负载,分配具有较高 CPU 核心数(如 16 - 32 核)的服务器,以满足大量数据的索引和查询操作;</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">协调节点(Coordinating)可以选择 CPU 核心数相对较少(如 8 - 16 核)但网络性能良好的服务器,用于高效地分发和接收查询请求。</span> </section></li> </ul> <h4 data-sourcepos="264:1-264:68" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">CPU优化的第二步:对线程池进行监控和动态调优</span></h4> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>ElasticSearch 线程池类型</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">ElasticSearch 中有多种线程池,如搜索线程池(</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">search</span></code> <span style="font-size: 15px;">)、索引线程池(</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">index</span></code> <span style="font-size: 15px;">)、批量线程池(</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">bulk</span></code> <span style="font-size: 15px;">)等。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">每个线程池负责不同类型的操作,并且其大小会影响 CPU 的利用率。例如:</span> </section> <ul data-sourcepos="274:1-276:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">搜索线程池(</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">search</span></code> <span style="font-size: 15px;">)大小决定了可以同时处理的搜索查询数量</span> </section></li> <li style="margin-top: 0.25em;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">索引线程池(</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">index</span></code> <span style="font-size: 15px;">)大小则影响数据索引的并发处理能力。</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>优化线程池大小</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">根据 CPU 核心数和集群的实际负载情况,合理调整线程池大小。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">一般来说,线程池大小不应超过 CPU 核心数的两倍,以避免过多的线程竞争 CPU 资源导致性能下降。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,在一个具有 16 核 CPU 的数据节点上,可以将搜索线程池大小设置为 30 左右,索引线程池大小设置为 20 左右。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">同时,可以通过监控工具(如 ElasticSearch 自带的监控 API 或者第三方监控工具)观察线程池的活跃线程数、队列长度等指标,根据这些指标动态调整线程池大小。</span> </section> <h4 data-sourcepos="289:1-289:60" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">使用 ElasticSearch 自带监控 API获取监控数据</span></h4> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">ElasticSearch 提供了丰富的 REST API 用于监控集群状态。可以通过访问</span> </section> <pre data-sourcepos="293:1-295:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">_cat/thread_pool<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">端点来获取线程池相关的信息。例如,发送一个 HTTP GET 请求到</span> </section> <pre data-sourcepos="299:1-301:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">http://<es-node-ip>:9200/_cat/thread_pool?v<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">v参数用于以详细格式返回结果),会返回类似如下内容:</span> </section> <pre data-sourcepos="307:1-324:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">pool_name active queue rejected<br>bulk 0 0 0<br>fetch 0 0 0<br>flush 0 0 0<br>generic 0 0 0<br>get 0 0 0<br>index 0 0 0<br>listener 0 0 0<br>management 0 0 0<br>percolate 0 0 0<br>refresh 0 0 0<br>search 0 0 0<br>snapshot 0 0 0<br>suggest 0 0 0<br>war m 0 0 0<br>write 0 0 0<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">其中,</span> </section> <ul data-sourcepos="328:1-331:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li> <section style="line-height: 1.75em;"> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">active</span></code> <span style="font-size: 15px;">列表示当前活跃的线程数,</span> </section></li> <li style="margin-top: 0.25em;"> <section style="line-height: 1.75em;"> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">queue</span></code> <span style="font-size: 15px;">列表示线程池队列中的任务数,</span> </section></li> <li style="margin-top: 0.25em;"> <section style="line-height: 1.75em;"> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">rejected</span></code> <span style="font-size: 15px;">列表示被拒绝的任务数。</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">通过这些核心指标,可以解每个线程池的负载情况。</span> </section> <h4 data-sourcepos="334:1-334:64" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">动态调整线程池大小(通过 API 或配置文件)</span></h4> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">如果发现 线程池负载高,或者 `queue 线程池队列中的任务数 积压多,可以进行动态调整线程池大小调整</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在 ElasticSearch 中,可以通过更新集群设置来动态调整线程池大小,可以使用下面的API,</span> </section> <pre data-sourcepos="340:1-342:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">_cluster/settings<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">发送一个 PUT类型的settings 请求,例如:</span> </section> <pre data-sourcepos="350:1-356:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">{<br> <span style="color: rgb(1, 86, 146);">"persistent"</span>: {<br> <span style="color: rgb(1, 86, 146);">"thread_pool.search.size"</span>: <span style="color: rgb(183, 85, 1);">30</span><br> }<br>}<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这个请求将搜索线程池(search)的大小调整为 30。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">需要注意的是,这种调整方式需要谨慎操作,并且最好在低峰期进行,因为不当的调整可能会对集群性能产生暂时的负面影响。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">另外,也可以通过修改elasticsearch.yml配置文件来调整线程池大小,不过这种方式需要重启集群才能生效。</span> </section> <h4 data-sourcepos="364:1-364:27" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">CPU 的优化建议:</span></h4> <ul data-sourcepos="366:1-375:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">确保服务器有足够的CPU核心,并合理调整Elasticsearch的线程池配置,可以提高系统的并发处理能力。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">推荐使用多核处理器(至少8核及以上)来提升处理能力。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">避免虚拟化过度使用,特别是在生产环境中,因为这可能会引入不必要的性能开销。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">对线程池进行监控和动态调优, 防止线程任务积压</span> </section></li> </ul> <h3 data-sourcepos="376:1-376:51" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">1.3 为ES进行 硬件层面的 网络优化:</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><br></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">建议为ES 使用 低延迟的网络 :</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">ES是天生自带分布式属性的,并且ES的分布式系统是基于对等网络的,节点与节点之间的通信十分的频繁,延迟对于ES的用户体验是致命的,所以对于ES来说,低延迟的网络是非常有必要的。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">高延迟的,跨多个数据中心的ES集群方案,是不太可取的,</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">虽然,ES可以容忍集群跨多个机房,可以有多个内网环境,支持跨AZ部署,但是不建议多个机房跨地域构建集群,</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><span style="color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";font-size: 15px;letter-spacing: normal;text-align: start;caret-color: rgb(36, 41, 46);">多个机房跨地域, </span>一旦发生了网络故障,集群可能直接雪崩,即使能够保证服务正常运行,维护这样(跨地域单个集群)的集群带来的额外成本可能远小于它带来的额外收益。</span> </section> <h2 data-sourcepos="394:1-394:26" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top-width: 1px;border-top-style: solid;border-top-color: rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">2 系统层面的优化</span></h2> <h3 data-sourcepos="396:1-396:60" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">2.1 为ES进行 系统层面的 文件句柄数 调优</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">修改ES启动用户可使用的系统文件句柄数,以适应Elasticsearch的需求。</span> </section> <h4 data-sourcepos="400:1-400:79" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">Elasticsearch 需要大量 的文件句柄数, 主要 两大 原因:</span></h4> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>第一:ES集群有大量的TCP /http 连接需求</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>大量的节点间通信连接</strong>:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">Elasticsearch 集群中节点之间, 需要进行频繁的通信。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">如数据同步、状态协调等,这会建立大量的 TCP 连接,每个 TCP 连接都需要占用一个文件句柄1。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>ES集群有大量的客户端连接</strong>:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">当有大量的 HTTP 客户端连接到 Elasticsearch 集群进行数据读写操作时,也会消耗大量的文件句柄。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">如果文件句柄数不足,可能导致新的连接无法建立,客户端出现连接超时等问题 。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>第二:ES集群有大量的索引与数据操作</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>ES集群有大量的索引文件操作</strong>:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">Elasticsearch 在处理索引时,会涉及到大量的文件操作。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,在索引创建、更新、删除过程中,需要打开和操作多个索引文件,包括索引元数据文件、数据文件、段文件等。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">每个文件都需要一个文件句柄,如果文件句柄数受限,可能会导致索引操作失败或异常。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>ES集群有大量的数据段合并</strong>:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">为了提高查询性能,Elasticsearch 会在后台进行数据段合并操作。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在合并过程中,需要同时打开多个段文件进行读写,如果文件句柄数不足,会影响段合并的效率,甚至导致合并失败 。</span> </section> <h4 data-sourcepos="432:1-432:77" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">问题:文件句柄数的 系统限制,满足不了es的句柄需求</span></h4> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>系统默认文件句柄数限制过低</strong>:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">许多 Linux 发行版默认每个进程允许的文件句柄数通常只有 1024 或更低,这对于处理大量数据和高并发请求的 Elasticsearch 来说远远不够。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>避免资源耗尽风险</strong>:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">如果不调整文件句柄数,当 Elasticsearch 的文件句柄使用达到系统默认限制时,继续请求打开文件就会失败,可能导致数据丢失、节点故障等严重问题 。</span> </section> <h4 data-sourcepos="446:1-446:61" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">调优:如何解除 文件句柄数的 系统限制?</span></h4> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>step1:查看当前系统文件句柄数限制</strong>:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">可以使用</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">ulimit -n</span></code> <span style="font-size: 15px;">命令查看当前文件描述符限制,默认通常是 1024,对于 ES 来说远远不够。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>step2:修改文件句柄数</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>临时修改文件句柄数</strong>:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">可以 通过</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">ulimit -n 65536</span></code> <span style="font-size: 15px;">命令将当前会话的文件描述符限制临时设置为 65536 。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>永久修改文件句柄数</strong>:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">使用</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">vim /etc/security/limits.conf</span></code> <span style="font-size: 15px;">命令编辑该limits.conf 文件,添加或修改以下配置项:</span> </section> <pre data-sourcepos="464:1-467:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">* soft nofile 65536<br>* hard nofile 65536<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">上述配置中,</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">*</span></code> <span style="font-size: 15px;">表示匹配所有用户,</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">soft</span></code> <span style="font-size: 15px;">为警告值,</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">hard</span></code> <span style="font-size: 15px;">为最大值。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>检查配置是否生效</strong>:重新登录系统后,使用</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">ulimit -n</span></code> <span style="font-size: 15px;">命令查看文件句柄数限制是否已生效</span> </section> <h3 data-sourcepos="479:1-479:49" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">2.2 为ES进行 系统层面的 swap 调优</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这里就是简单粗暴,关掉swap。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">内存交换 到磁盘对服务器性能来说是 致命 的。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">如果内存交换到磁盘上,性能就会急剧下降, 一个 100 微秒的操作可能变成 10 毫秒,下降100倍以上。想想那么多 10 微秒的操作时延累加起来。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">不难看出 swapping 对于性能是多么可怕。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">所以,Elasticsearch建议禁用Swap分区,因为当物理内存不足时,操作系统会将一些内存页交换到磁盘上,这会导致性能急剧下降。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在Linux系统中, 用以下命令关掉swap:</span> </section> <pre data-sourcepos="497:1-499:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">sudo swapoff -a<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在Linux系统中使用ES,最好可以通过修改</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">/etc/sysctl.conf</span></code> <span style="font-size: 15px;">文件来禁用Swap分区:</span> </section> <pre data-sourcepos="507:1-510:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;"># 在文件末尾添加以下行<br>vm.swappiness=<span style="color: rgb(183, 85, 1);">1</span><br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">然后运行</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">sudo sysctl -p</span></code> <span style="font-size: 15px;">使配置生效。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>除了 关掉swap ,还可以 使用 memlock ,为ES 锁定的物理内存。</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">memlock 是一个与内存锁定相关的系统资源限制。它用于指定一个进程能够锁定的物理内存(RAM)的大小。内存锁定意味着将进程使用的内存固定在物理内存中,防止操作系统将其交换(swap)到磁盘上的虚拟内存(磁盘交换空间)。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">对于像 Elasticsearch 这样的应用程序,将内存锁定是很重要的。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">因为 Elasticsearch 大量使用内存来缓存索引数据,如果这些数据被交换到磁盘,会导致查询性能大幅下降。内存锁定可以确保关键的内存区域(如索引缓存)始终在物理内存中,提高数据访问速度。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">可以通过设置Elasticsearch的</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">bootstrap.memory_lock</span></code> <span style="font-size: 15px;">选项来尝试锁定JVM内存,防止其被交换到磁盘上, 在 配置文件elasticsearch.yml中添加以下行</span> </section> <pre data-sourcepos="526:1-529:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">bootstrap.memory_lock: <span style="color: rgb(183, 85, 1);">true</span><br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>注意</strong>:这需要用户 有</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">memlock</span></code> <span style="font-size: 15px;">权限。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">可以通过</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">ulimit -l</span></code> <span style="font-size: 15px;">命令查看当前用户的</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">memlock</span></code> <span style="font-size: 15px;">限制,并通过</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">ulimit -l unlimited</span></code> <span style="font-size: 15px;">命令设置无限制(但这通常需要root权限)。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在生产环境中,更推荐的方式是通过修改</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">/etc/security/limits.conf</span></code> <span style="font-size: 15px;">文件来永久设置 memlock 限制。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">通过修改</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">/etc/security/limits.conf</span></code> <span style="font-size: 15px;">文件来永久设置</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">memlock</span></code> <span style="font-size: 15px;">限制,可按以下步骤进行操作:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">用文本编辑器打开</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">/etc/security/limits.conf</span></code> <span style="font-size: 15px;">文件, 在文件末尾添加或修改以下内容 :</span> </section> <pre data-sourcepos="543:1-546:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">* soft memlock [期望的软限制大小]<br>* hard memlock [期望的硬限制大小]<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,如果想将</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">memlock</span></code> <span style="font-size: 15px;">限制设置为 8GB(以字节为单位),则可写成:</span> </section> <pre data-sourcepos="554:1-557:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">* soft memlock 8388608<br>* hard memlock 8388608<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这里的</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">*</span></code> <span style="font-size: 15px;">表示匹配所有用户,你也可以根据实际情况指定具体的用户,如</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">elastic soft memlock 8388608</span></code> <span style="font-size: 15px;">和</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">elastic hard memlock 8388608</span></code> <span style="font-size: 15px;">,只对</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">elastic</span></code> <span style="font-size: 15px;">用户生效 。</span> </section> <h2 data-sourcepos="569:1-569:25" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top-width: 1px;border-top-style: solid;border-top-color: rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">3 JVM层面的优化</span></h2> <h2 data-sourcepos="573:1-573:52" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top-width: 1px;border-top-style: solid;border-top-color: rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">3.1 为ES进行 JVM层面的 JVM堆大小调优</span></h2> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">Elasticsearch是运行在JVM上的,对其做JVM参数调优至关重要。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">最常见的调优是Java内存的分配。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">下面是JVM的内存模型,具体每块的作用,不在这里阐述。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <img class="rich_pages wxw-img" data-imgfileid="100020697" data-ratio="0.5806451612903226" src="/upload/48a318301da6e990f78479f26c68778e.png" data-w="744" style="box-sizing: content-box;border-style: none;background-color: rgb(255, 255, 255);"> </section> <h3 data-sourcepos="583:1-583:58" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">新生代和老年代分配的内存比例给多大?</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">Jvm内存分为新生代和老年代。</span> </section> <ul data-sourcepos="587:1-602:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">新生代(或者伊甸园)</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">新实例化的对象分配的空间。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">新生代空间通常都非常小,一般在 100 MB–500 MB。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">新生代也包含两个 幸存 空间。</span> </section></li> <li style="margin-top: 0.25em;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">老年代</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">较老的对象存储的空间。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">这些对象预计将长期留存并持续上很长一段时间。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">老生代通常比新生代大很多。</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">新生代、老生代的垃圾回收都有一个阶段会“stop the world”。给新生代和老年代分配多大的内存呢?他们的比例是多少呢?</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">一般来说,老年代和新生代的内存比例为2:1是比较合适的。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">比如给堆内存分配3G,则新生代分配1G,其余都给老年代。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在ElasticSearce的配置文件jvm.options文件配置:</span> </section> <pre data-sourcepos="611:1-615:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">-Xms3g //配置堆初始化大小<br>-Xmx3g //配置堆的最大内存<br>-Xmn1g //配置新生代内存。<br></span> </section></pre> <h3 data-sourcepos="617:1-617:51" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">一个Elasticesearch节点的两个内存大户</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">内存对于 Elasticsearch 来说绝对是重要的,它可以被许多内存数据结构使用来提供更快的操作。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">一台机器装一个Elasticesearch节点,我们应该怎么分配机器的内存呢?</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">官方给出了解决方案,把一半(少于)的内存分配给Luence,另外的内存分配给ElasticSearch.</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">是一个Elasticesearch内存大户,底层的 Luence 另一个内存大户:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>第一个 内存大户Elasticsearch 缓存</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">(1) 文档 缓存数据</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">最重要的是缓存索引数据。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">首先 是 文档数据缓存。 当执行查询操作时,经常访问的文档数据会被缓存在堆内存中。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如:一个电商商品搜索系统使用 Elasticsearch,用户频繁搜索的热门商品信息(如商品名称、价格、品牌等)会被缓存,这样在后续查询时可以快速从内存中获取,减少磁盘 I/O 操作,提高查询响应速度。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">其次 是过滤器缓存, 也存储在堆内存中。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">当使用过滤器进行查询(如筛选出特定品牌的商品)时,过滤器的结果会被缓存,下次遇到相同的过滤条件时可以直接利用缓存结果,提高过滤效率。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">(2) 索引缓冲区</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在数据写入索引的过程中,会有一个索引缓冲区(Index Buffer)在堆内存中。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">新的数据首先进入这个缓冲区,当缓冲区满或者达到一定的阈值时,数据会被刷新到磁盘上的索引文件中。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">(3) 查询相关数据结构</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">存储查询执行过程中的临时数据结构,如用于排序的字段值集合。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,对商品按照价格进行排序的查询,排序过程中的价格数据会暂存在堆内存中。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">还有聚合操作的中间结果,比如在统计不同品牌商品数量的聚合查询中,每个品牌的计数中间结果会存储在堆内存。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">(4) 集群状态 缓存</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">Elasticsearch 主节点需要在堆内存中存储集群状态信息,包括索引元数据(如索引名称、分片数量、副本数量等)、节点信息(如节点角色、节点健康状态等)。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这些信息对于集群的管理和协调至关重要,如在进行分片分配、故障转移等操作时会使用到这些信息。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>第二个 内存大户 Lucene 非堆内存(off - heap)</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">(1) 索引文件数据</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">Lucene 是 Elasticsearch 的底层搜索引擎库,大部分索引数据实际上存储在非堆内存(磁盘文件)中。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">索引文件包含了倒排索引,倒排索引是 Lucene 的核心数据结构。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,对于文档中的每个单词,倒排索引记录了包含该单词的文档列表。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在文本搜索场景下,如新闻网站的文章搜索,文章中的词汇和对应的文档编号存储在非堆内存的索引文件中,用于快速定位包含特定词汇的文章。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">(2) 段文件(Segment Files)存储在非堆内存中。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">Lucene 会将索引划分为多个段,每个段是一个独立的索引部分。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这些段文件包含了文档数据、词向量等信息,并且会根据一定的策略进行合并和优化。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,在数据更新过程中,新的数据可能会形成新的段,然后通过段合并操作来优化索引结构,这些段文件存储在非堆内存中。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">(3)文件系统缓存</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">操作系统会对磁盘上的索引文件进行缓存,这部分缓存数据虽然不在 Java 堆内存中, 也是(off - heap)非堆内存的一部分。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">当 Lucene 读取索引文件时,操作系统会将最近访问的文件块缓存在内存中,提高文件的访问速度。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,频繁被查询的索引段文件部分会被操作系统缓存,下次访问时可以直接从缓存中读取,减少磁盘读取时间。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">Lucene 使用 内存映射文件(Memory - Mapped Files)数据,将磁盘上的索引文件映射到内存中,使得文件访问就像访问内存一样高效。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这部分内存映射的数据也属于非堆内存。通过这种方式,Lucene 可以直接在内存中操作索引文件的部分内容,而不需要进行大量的文件 I/O 操作,提高了索引数据的读写效率。</span> </section> <h3 data-sourcepos="697:1-697:48" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">该分配多大的内存给Elasticesearch?</span></h3> <ul data-sourcepos="701:1-708:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">如果 把所有的内存都分配给 Elasticsearch 的堆内存,那将不会有剩余的内存交给 Lucene。这将严重地影响全文检索的性能。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">标准的建议是把 50% 的可用内存作为 Elasticsearch 的堆内存,保留剩下的 50%,Lucene 会很乐意利用起余下的内存,也就是把 50% 的可用内存作为 Lucene 的非堆内存(off - heap)。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">Lucene 被设计为可以利用操作系统底层机制来缓存内存数据结构,所以这部分Lucene 的非堆内存(off - heap),预留就OK了,不需要专门设置。</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">所以,在使用Elasticesearch的时候,按照实际的系统内存大小,一般进行Elasticesearch堆大小进行对应的配置,从最小规格的8G(如果 os内存 16g) 到了中等规模16G内存(如果 os内存 32g),然后最大规格32G内存(如果 os内存>64g)。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">分配的建议如下:</span> </section> <ul data-sourcepos="713:1-720:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">如果 os内存 16g ,jvm 8G</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">如果 os内存 32g ,jvm 16g</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">如果 os内存>64g ,jvm 32g</span> </section></li> </ul> <h4 data-sourcepos="721:1-721:23" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">Xms和Xmx设置:</span></h4> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">合理设置堆内存大小, 一般建议将堆内存设置为物理内存的 50 - 70%。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">通过-Xms(初始堆大小)和-Xmx(最大堆大小)参数来设置初始堆大小、最大堆大小 相同。例如:</span> </section> <pre data-sourcepos="729:1-732:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">-Xms30g<br>-Xmx30g<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">确保</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">-Xms</span></code> <span style="font-size: 15px;">和</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">-Xmx</span></code> <span style="font-size: 15px;">的值相同,这样可以避免在堆内存扩展或收缩过程中产生性能开销。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">建议将JVM堆内存的初始大小(-Xms)和最大大小(-Xmx)设置为相同的值,以避免运行过程中动态调整堆内存大小,这是一个损耗性能的操作。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">可以通过修改</span> </section> <pre data-sourcepos="740:1-742:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">jvm.options<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">文件来调整堆内存的大小。例如,将堆内存设置为16GB的配置如下:</span> </section> <pre data-sourcepos="746:1-749:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">-Xms16g<br>-Xmx16g<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这里将堆内存的初始大小和最大大小都设置为16GB,你可以根据实际情况调整</span> </section> <h3 data-sourcepos="757:1-757:76" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">分配给Elasticesearch 最大内存应该小于 32766 mb(~31.99 gb)</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">为啥呢? JVM 在内存小于 32 GB 的时候会采用一个内存对象指针压缩技术。</span> </section> <ul data-sourcepos="761:1-764:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">对于 32 位的系统,意味着堆内存大小最大为 4 GB。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">对于 64 位的系统, 可以使用更大的内存,但是 64 位的指针意味着更大的浪费,因为你的指针本身大了。</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">更糟糕的是, 更大的指针在主内存和各级缓存(例如 LLC,L1 等)之间移动数据的时候,会占用更多的带宽。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">所以, 为了节省 64 位的指针 占用内存的大小, Java 使用一个叫作 内存指针压缩(compressed oops)的技术来解决这个问题。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">使用 内存指针压缩(compressed oops)的技术, 对象的指针不再表示对象在内存中的精确位置,而是表示 偏移量 。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这意味着 32 位的指针可以引用 40 亿个 对象 , 而不是 40 亿个字节。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">从极端角度来说,假设一个对象一个字节,使用 内存指针压缩(compressed oops)的技术后, , 32 位的指针表示对象的指针理解为,最大增长到 32 GB 的物理内存。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">一旦你越过那个神奇的 ~32 GB 的边界,指针就会切回普通对象的指针。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">切回普通对象的64位指针,每个对象的指针都变长了,就会使用更多的 CPU 内存带宽,也就是说你实际上失去了更多的内存。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">事实上,哪怕是 40–50 GB 内存,和使用了内存对象指针压缩技术时候的 32 GB 内存的 效果是一样的, 10多个G白白的给普通对象的64位指针了 。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">总之:即便你有足够的内存,JVM 也尽量不要 超过 32 GB。因为它浪费了内存,降低了 CPU 的性能,还要让 GC 应对大内存。</span> </section> <h2 data-sourcepos="785:1-785:31" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top-width: 1px;border-top-style: solid;border-top-color: rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">3.2 垃圾回收器的优化</span></h2> <h3 data-sourcepos="789:1-789:38" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">3.2.1:JDK8 + G1 垃圾回收器</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">很多公司生产环境使用的是老的es 6 系列版本(比较稳定),如</span> </section> <ul data-sourcepos="795:1-802:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;"><strong>JDK</strong>:JDK1.8_171-b11 (64位)</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;"><strong>ES集群</strong>:一般由3台16核32G的虚拟机部署 ES 集群,每个节点分配16G堆内存</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;"><strong>ELK版本</strong>:6.3.0</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;"><strong>垃圾回收器</strong>:ES 默认指定的老年代(CMS)+ 新生代(ParNew)</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;"><strong>操作系统</strong>:CentOS Linux release 7.4.1708(Core)</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">Elasticsearch 默认的垃圾回收器( GC )是 CMS。官方建议使用 CMS。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这个垃圾回收器可以和应用并行处理,以便它可以最小化停顿。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">然而,它有两个 stop-the-world 阶段,但是 CMS处理大内存也有点吃力。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>启用 G1 垃圾回收器</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在 Elasticsearch 的 jvm.options文件中,将默认的垃圾回收器设置为 G1。找到以下行(如果不存在可以添加):</span> </section> <pre data-sourcepos="817:1-819:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">-XX:+UseG1GC<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这会告诉 JVM 使用 G1 垃圾回收器来管理内存。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>设置 G1堆内存 参数</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">根据堆内存大小来调整 G1 的相关参数。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">第一:确定 G1 垃圾回收器的堆内存区域(Region)大小:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">-XX:G1HeapRegionSize</span></code> <span style="font-size: 15px;">参数用于确定 G1 垃圾回收器的堆内存区域(Region)大小。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">其默认值会根据堆内存大小自动调整,但在某些情况下可能需要手动优化。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">计算公式为:</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">1M <= G1HeapRegionSize <= 32M</span></code> <span style="font-size: 15px;">,并且</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">堆内存大小 / G1HeapRegionSize = Region数量</span></code> <span style="font-size: 15px;">应该是</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">2^n</span></code> <span style="font-size: 15px;">。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,对于 30GB 的堆内存,可以尝试将</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">-XX:G1HeapRegionSize</span></code> <span style="font-size: 15px;">设置为</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">16M</span></code> <span style="font-size: 15px;">,这样</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">Region</span></code> <span style="font-size: 15px;">数量为</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">30 * 1024 / 16 = 1920</span></code> <span style="font-size: 15px;">(近似值),是一个比较合适的数值。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">第二:优化停顿时间相关参数</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">设置最大停顿时间目标,使用</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">-XX:MaxGCPauseMillis</span></code> <span style="font-size: 15px;">参数来控制 G1 垃圾回收器的最大停顿时间目标。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,设置为</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">200</span></code> <span style="font-size: 15px;">表示希望垃圾回收的停顿时间尽量不超过 200 毫秒。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">但要注意,设置的值过小可能会导致 G1 频繁地进行垃圾回收以满足停顿时间要求,反而增加了总的垃圾回收时间。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">需要根据实际的业务场景和性能测试来调整这个参数。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">第三:调整混合垃圾回收(Mixed GC)的触发条件</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">G1 会在一定条件下触发混合垃圾回收,即同时回收年轻代和部分老年代。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">可以通过</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">-XX:InitiatingHeapOccupancyPercent</span></code> <span style="font-size: 15px;">参数来调整触发混合垃圾回收的堆内存占用比例。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,将其设置为</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">45</span></code> <span style="font-size: 15px;">,表示当堆内存占用达到 45% 时,G1 开始考虑触发混合垃圾回收。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这个参数的调整需要综合考虑堆内存大小、对象分配速率和停顿时间要求等因素。</span> </section> <h3 data-sourcepos="869:1-869:38" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">3.2.2:jdk17 + ZGC垃圾回收器</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">45岁老架构师尼恩建议,如果条件允许,可以升级jdk版本,提升性能。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">那为什么要升级到jdk17呢,主要是由于:</span> </section> <ul data-sourcepos="875:1-880:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">1、jdk17的g1垃圾回收期相较于jdk11,提升到15%左右。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">2、在jdk17中,有向量化支持,同时在字符串处理等方面做了一些优化,相对于集群的写入压力会小很多。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">3、在jdk17中,对于ZGC的适配做了一些加强,这个ZGC的垃圾回收器比G1稳定性和性能有很大的提升。</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在考虑把jdk的版本升级到jdk17去,同时尽量把elasticsearch的版本更新到最新的版本去。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在完成了jdk17的升级之后,下一步考虑的就是配置ZGC垃圾回收器。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">ZGC垃圾回收器是一个并发的、单代的、基于区域的、NUMA 感知的垃圾回收器,Stop-the-world 阶段仅限于根扫描,因此 GC 暂停时间不会随堆或 live set 的变大而增加。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">而且ZGC垃圾回收期在回收的过程中几乎是全程并发处理,如下图:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <img class="rich_pages wxw-img" data-imgfileid="100020699" data-ratio="0.5185185185185185" src="/upload/c39675951add45f35e6628c2e788da30.png" data-type="png" data-w="1080" style="box-sizing: content-box;border-style: none;background-color: rgb(255, 255, 255);"> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">所以对于短暂停顿的时间来说非常小,几乎可以忽略不计。下面我们来演示下配置ZGC的垃圾回收器方法。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">关于zgc的文章,尼恩后续写一个系统化的介绍, 帮助大家穿透zgc。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在elasticsearch的config目录下有一个jvm.options文件</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <img class="rich_pages wxw-img" data-imgfileid="100020700" data-ratio="0.11587982832618025" src="/upload/77f338e33f0dd1faad07cf478e965797.png" data-type="png" data-w="932" style="box-sizing: content-box;border-style: none;background-color: rgb(255, 255, 255);"> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">打开后,找到如下部分:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <img class="rich_pages wxw-img" data-imgfileid="100020698" data-ratio="0.29463171036204744" src="/upload/4404bfa4ebe368cc1b3c761424fc04a7.png" data-type="png" data-w="801" style="box-sizing: content-box;border-style: none;background-color: rgb(255, 255, 255);"> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">因为我们的jdk版本是jdk17,所以找到14-的地方把这里所有的东西注释掉,然后添加如下的代码:</span> </section> <pre data-sourcepos="909:1-912:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;"><span style="color: rgb(183, 85, 1);">14</span>-:-XX:+UseZGC<br><span style="color: rgb(183, 85, 1);">14</span>-:-XX:+UnlockExperimentalVMOptions<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">最后的样子如下图:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <img class="rich_pages wxw-img" data-imgfileid="100020701" data-ratio="0.37454545454545457" src="/upload/30fe6498d0d9cd6e61f979e6649e272c.png" data-type="png" data-w="825" style="box-sizing: content-box;border-style: none;background-color: rgb(255, 255, 255);"> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">此时我们就配制好了当前的elasticsearch的环境使用ZGC垃圾收集器。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">然后我们启动下elasticsearch,启动完成后在日志中查找下ZGC关键词,如下图:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <img class="rich_pages wxw-img" data-imgfileid="100020703" data-ratio="0.13425925925925927" src="/upload/6b8ccf40da363556e2d8f700b686d1e6.png" data-type="png" data-w="1080" style="box-sizing: content-box;border-style: none;background-color: rgb(255, 255, 255);"> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">可以看到启动的时候使用的是ZGC垃圾收集器。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">以上就是ZGC垃圾收集器的配置全过程。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">1、zgc垃圾收集器从jdk11版本开始支持,所以只要是jdk11及以上的版本都支持zgc垃圾收集器。 2、zgc垃圾收集器的由于是并行进行处理,所以生产环境中ZGC的垃圾收集停顿时间不超过10ms,可以放心大胆的使用起来。 3、使用ZGC是并行的进行垃圾回收,所以有时候会发生查询耗时增加的情况,可以在jvm.options文件中添加如下的参数:-XX:+UseDynamicNumberOfGCThreads 代表动态配置GC线程,降低CPU的使用量,这个是JDK17的新特性,在jdk17以下是没有这个参数的。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">具体如下图:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <img class="rich_pages wxw-img" data-imgfileid="100020702" data-ratio="0.5011764705882353" src="/upload/e777bd7485cb179df847b4c2541b63b0.png" data-type="png" data-w="850" style="box-sizing: content-box;border-style: none;background-color: rgb(255, 255, 255);"> </section> <h3 data-sourcepos="957:1-957:38" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">Elasticsearch的内存优化总结</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">Elasticsearch的内存配置是其性能优化中非常重要的一部分。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">以下是一些关键点:</span> </section> <ul data-sourcepos="966:1-974:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">Elasticsearch默认将JVM堆内存设置为1GB或系统物理内存的一半,取较小值。但是这个默认值可能不适合所有场景,因此需要根据实际情况进行调整。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">官方建议堆内存大小不要超过32GB,因为当堆大小超过32GB时,JVM会使用64位指针,这会导致更多的内存消耗和额外的开销。如果需要更大的堆内存,可以考虑增加节点数量而不是单个节点的堆内存大小。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">堆内存应该合理分配给Elasticsearch进程,同时要确保操作系统和其他进程有足够的内存可用。通常,将机器总内存的50%到60%分配给Elasticsearch是合理的,剩下的内存留给操作系统缓存和其他服务。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">对垃圾回收器进行优化,可以使用zgc</span> </section></li> </ul> <h2 data-sourcepos="975:1-975:40" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top-width: 1px;border-top-style: solid;border-top-color: rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">4 ElasticSearch集群层面的优化</span></h2> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">Elasticsearch</span></code> <span style="font-size: 15px;">的核心架构,是围绕着节点(</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">Node</span></code> <span style="font-size: 15px;">)和集群(</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">Cluster</span></code> <span style="font-size: 15px;">)展开。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">节点是</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">Elasticsearch</span></code> <span style="font-size: 15px;">的运行实例,每个节点都承担着特定的任务和职责。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">多个节点组成一个集群,通过分布式的方式存储和处理数据,实现了高可用性、可扩展性和高性能。</span> </section> <h2 data-sourcepos="987:1-987:33" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top-width: 1px;border-top-style: solid;border-top-color: rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">4.1. Elasticsearch节点概述</span></h2> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <br> </section> <p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-imgfileid="100020704" data-ratio="0.812962962962963" data-s="300,640" src="/upload/ed1fb709b6f6b1c88fe5671cddf8a5de.png" data-type="png" data-w="1080" style=""></p> <h3 data-sourcepos="991:1-991:31" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">4.1.1 节点的基本概念</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">Elasticsearch</span></code> <span style="font-size: 15px;">中,<strong>节点(Node)</strong> 是一个运行中的</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">Elasticsearch</span></code> <span style="font-size: 15px;">实例。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">它是集群的基本组成单元,负责<strong>存储数据</strong>、<strong>处理查询请求</strong>以及<strong>与其他节点进行通信</strong>。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">每个节点都有一个唯一的标识符,用于在集群中进行识别和通信。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <br> </section> <p style="text-align: center;"><img class="rich_pages wxw-img js_insertlocalimg" data-imgfileid="100020705" data-ratio="1" data-s="300,640" src="/upload/a81c28534c2b88accc66559cfe10d19d.png" data-type="png" data-w="1024" style=""></p> <h3 data-sourcepos="1001:1-1001:31" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">4.1.2 节点的类型划分</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">Elasticsearch</span></code> <span style="font-size: 15px;">中的节点可以根据其<strong>功能和角色</strong>进行不同的划分,常见的节点类型包括:</span> </section> <h5 data-sourcepos="1005:1-1005:40" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">4.1.2.1 主节点(Master Node)</span></h5> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>主节点</strong> 负责管理整个集群的状态,包括节点的加入和离开、索引的创建和删除、分片的分配和迁移等。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">主节点并不负责处理数据的存储和查询,它的主要职责是维护集群的元数据和协调各个节点的工作。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">以下是一个简单的示例,展示如何在Elasticsearch的配置文件中设置节点为主节点:</span> </section> <pre data-sourcepos="1013:1-1018:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;"><span style="color: rgb(1, 86, 146);">node.name:</span> <span style="color: rgb(84, 121, 13);">master-node</span><br><span style="color: rgb(1, 86, 146);">node.master:</span> <span style="color: rgb(183, 85, 1);">true</span><br><span style="color: rgb(1, 86, 146);">node.data:</span> <span style="color: rgb(183, 85, 1);">false</span><br><br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在上述配置中,</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">node.master</span></code> <span style="font-size: 15px;"> 设置为 </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">true</span></code> <span style="font-size: 15px;"> 表示该节点可以作为候选主节点,</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">node.data</span></code> <span style="font-size: 15px;"> 设置为 </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">false</span></code> <span style="font-size: 15px;"> 表示该节点不存储数据。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这里设置的是候选主节点,真正的主节点通过选举产生,<strong>45岁老架构师尼恩提示, es 集群只能有一个 真正主节点。</strong></span> </section> <h5 data-sourcepos="1024:1-1024:41" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">4.1.2.2 数据节点(Data Node)</span></h5> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>数据节点</strong> 负责存储和检索数据。它是集群中最核心的节点类型,负责处理文档的索引和查询操作。数据节点会将数据按照一定的规则进行分片存储,以实现数据的分布式存储和并行处理。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">以下是一个设置数据节点的示例配置:</span> </section> <pre data-sourcepos="1030:1-1035:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;"><span style="color: rgb(1, 86, 146);">node.name:</span> <span style="color: rgb(84, 121, 13);">data-node</span><br><span style="color: rgb(1, 86, 146);">node.master:</span> <span style="color: rgb(183, 85, 1);">false</span><br><span style="color: rgb(1, 86, 146);">node.data:</span> <span style="color: rgb(183, 85, 1);">true</span><br><br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在这个配置中,</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">node.master</span></code> <span style="font-size: 15px;"> 设置为 </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">false</span></code> <span style="font-size: 15px;"> 表示该节点不作为主节点,</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">node.data</span></code> <span style="font-size: 15px;"> 设置为 </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">true</span></code> <span style="font-size: 15px;"> 表示该节点是数据节点。</span> </section> <h5 data-sourcepos="1039:1-1039:49" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">4.1.2.3 协调节点(Coordinating Node)</span></h5> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>协调节点</strong> 负责<strong>接收客户端的查询请求</strong>,并<strong>将请求转发到合适的数据节点进行处理</strong>。协调节点会收集各个数据节点的查询结果,并进行合并和排序,最终将结果返回给客户端。协调节点本身不存储数据,它的主要作用是协调和管理查询请求的处理过程。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">以下是一个设置协调节点的示例配置:</span> </section> <pre data-sourcepos="1045:1-1052:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;"><span style="color: rgb(1, 86, 146);">node.name:</span> <span style="color: rgb(84, 121, 13);">coordinating-node</span><br><span style="color: rgb(1, 86, 146);">node.master:</span> <span style="color: rgb(183, 85, 1);">false</span><br><span style="color: rgb(1, 86, 146);">node.data:</span> <span style="color: rgb(183, 85, 1);">false</span><br><span style="color: rgb(1, 86, 146);">node.ingest:</span> <span style="color: rgb(183, 85, 1);">false</span><br><span style="color: rgb(1, 86, 146);">search.remote.connect:</span> <span style="color: rgb(183, 85, 1);">false</span><br><br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在这个配置中,除了将 </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">node.master</span></code> <span style="font-size: 15px;"> 和 </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">node.data</span></code> <span style="font-size: 15px;"> 设置为 </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">false</span></code> <span style="font-size: 15px;"> 外,还将 </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">node.ingest</span></code> <span style="font-size: 15px;"> 和 </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">search.remote.connect</span></code> <span style="font-size: 15px;"> 设置为 </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">false</span></code> <span style="font-size: 15px;">,以确保该节点只作为协调节点。</span> </section> <h3 data-sourcepos="1056:1-1056:31" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">4.1.3 节点的通信机制</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">Elasticsearch</span></code> <span style="font-size: 15px;">中的节点通过 <strong>TCP</strong> 协议进行通信。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">节点之间会建立连接,通过发送和接收消息来进行数据的传输和交互。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">节点之间的通信是基于请求-响应模型的,一个节点发送请求,另一个节点接收请求并返回响应。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">为了提高通信效率和可靠性,Elasticsearch采用了一些优化措施,例如:</span> </section> <ul data-sourcepos="1066:1-1075:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;"><strong>连接池</strong>:节点会维护一个连接池,用于管理与其他节点的连接。连接池可以复用已建立的连接,减少连接的建立和销毁开销。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;"><strong>消息压缩</strong>:在节点之间传输消息时,Elasticsearch会对消息进行压缩,以减少网络传输的数据量。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;"><strong>异步通信</strong>:节点之间的通信采用异步方式,发送请求后可以继续执行其他操作,不需要等待响应返回。</span> </section></li> </ul> <h2 data-sourcepos="1076:1-1076:31" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top-width: 1px;border-top-style: solid;border-top-color: rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">4.2 合理划分节点角色</span></h2> <h3 data-sourcepos="1082:1-1082:34" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">4.2.1 主节点(Master):</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">主节点负责集群的管理和元数据存储,如索引的创建、删除、分片分配等操作。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">为了确保集群的稳定性,应该选择性能稳定、网络连接良好的节点作为主节点。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">一般建议将主节点与数据节点分离,避免主节点因处理大量的数据存储和查询任务而负载过重。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,在一个大规模的日志分析集群中,可以选择 3 - 5 个配置较高的节点作为master candidate 主节点候选节点,并且这些节点最好分布在不同的机架或数据中心,以防止单点故障。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">同时,合理设置最小主节点,通过minimum_master_nodes 完成。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">minimum_master_nodes 设置及其重要,为了防止集群脑裂,这个参数应该设置为法定个数就是 ( master 候选节点个数 / 2) + 1。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>minimum_master_nodes的定义与作用</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">minimum_master_nodes</span></code> <span style="font-size: 15px;">是 Elasticsearch 集群中的一个重要设置,用于定义在集群中可以正常选举主节点(Master)的最少候选主节点数量。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">minimum_master_nodes 的主要目的是防止集群出现 “脑裂(split - brain)” 现象。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">脑裂是指在集群中,由于网络分区或其他原因,导致多个节点分别认为自己是主节点,从而使集群分裂成多个独立的部分,这会导致数据不一致和集群的混乱。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">通过设置</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">minimum_master_nodes</span></code> <span style="font-size: 15px;">,可以确保在选举主节点时,只有当足够数量的候选主节点能够相互通信时,才能成功选举出主节点,从而避免脑裂情况的发生。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>计算minimum_master_nodes的合适值</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">计算</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">minimum_master_nodes</span></code> <span style="font-size: 15px;">的公式为:</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">(master_eligible_nodes / 2) + 1</span></code> <span style="font-size: 15px;">,</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">其中</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">master_eligible_nodes</span></code> <span style="font-size: 15px;">是集群中具有主节点选举资格的节点数量。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,在一个有 5 个具有主节点选举资格的节点的集群中,</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">minimum_master_nodes</span></code> <span style="font-size: 15px;">的值应该是</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">(5 / 2) + 1 = 3</span></code> <span style="font-size: 15px;">(向上取整)。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这意味着在进行主节点选举时,至少需要 3 个候选主节点能够相互通信,才能成功选举出主节点。</span> </section> <h3 data-sourcepos="1122:1-1122:44" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">4.2.2 数据节点(Data)的配置:</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">数据节点主要负责存储和索引数据,它们会占用大量的磁盘空间和 I/O 资源。根据数据量和查询负载来合理分配数据节点的数量。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">如果数据量增长迅速或者查询并发量较高,可以适当增加数据节点。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">同时,要注意数据节点的硬件配置,如配备足够的内存来缓存索引数据,使用高性能的磁盘(如 SSD)来提高数据读写速度。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">除此之前,数据节点(Data)的配置的配置,和数据规模有关。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">预估存储一个亿文档的 Elasticsearch 数据节点数量需要综合多方面因素考虑,以下是一些分析:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>第一,评估数据量与存储</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>单个文档大小估算</strong>:假设每个文档平均大小为 1KB,那么一亿个文档大约需要 100GB 的存储空间。如果考虑副本以及索引的额外开销,实际所需空间会更大。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>节点存储容量规划</strong>:通常情况下,一个数据节点的磁盘容量建议不超过其总容量的 70% 至 80%,以预留一定空间用于数据的临时写入和系统文件存储等。如果使用普通机械硬盘,每个节点的存储容量可以控制在 2TB 至 3TB 左右;如果是 SSD 硬盘,可根据其性能和成本适当增加存储容量,但也不建议超过单节点 5TB 左右的存储量。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>第二,规划分片与副本</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>分片数量</strong>:根据经验,分片大小保持在 10GB 至 50GB 之间较为合适。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">对于一亿个文档( 100GB),若按每个分片 30GB 左右估算,大约需要 4 至 5 个主分片。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">同时,还需要考虑副本数量,通常副本数量可以设置为 1 至 2 个,以提高数据的可用性和查询性能。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>节点承载分片数</strong>:每个数据节点能够承载的分片数量也有限制,官方一般建议每 GB 堆内存对应少于 20 个分片。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">其实,官方的这个建议,这个其实性能很低的。为什么呢 ?</span> </section> <ul data-sourcepos="1156:1-1161:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">按照官方建议,一个具有 32GB 堆内存的数据节点,最多可承载 640 个分片左右, 对应到的磁盘空间 640 *30G =19200G 。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">假设缓存16G,对19200G 的数据进行缓存,当然 这么少的内存,这么大规模的数据,这个内存的缓存的作用,可以说聊胜于无,没啥命中率的。</span> </section></li> </ul> <h3 data-sourcepos="1162:1-1162:31" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">如果估算数据节点数</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">怎么估算较好呢?</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">尼恩的经验, 可以按照 内存需求,反向计算节点数。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">一般来说, 最好有磁盘空间的30%以上的内存空间,作为 堆内存。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">当然,这个比例越高,性能越好。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">比如有磁盘空间的50%以上的内存空间, es的性能越高。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">那么, 一亿个文档( 100GB),加速副本最少 200G, 最好有60个G的内存。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">假设一个节点 16G内存, 那么 需要 5个节点。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">当然,如果有10个节点, 性能会更好。</span> </section> <h3 data-sourcepos="1182:1-1182:52" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">4.2.3 协调节点(Coordinating)的配置:</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">协调节点负责接收用户查询请求,并将请求分发到合适的数据节点进行处理,然后汇总结果返回给用户。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">协调节点需要有良好的网络和 CPU 性能,以快速地转发和处理查询。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在集群中,可以根据查询流量来设置协调节点的数量,一般可以按照一定的比例(如每 10 个数据节点配置 2 - 3 个协调节点)来配置。</span> </section> <h2 data-sourcepos="1198:1-1198:37" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top-width: 1px;border-top-style: solid;border-top-color: rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">4.3 ES 数据节点的写入调优</span></h2> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">ES 数据写入具有一定的延时性,这是为了减少频繁的索引文件产生。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">另外,在搜索引擎的业务场景下,用户一般并不需要那么高的写入实时性。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">比如 在网站发布一条征婚信息,或者二手交易平台发布一个商品信息。其他人并不是马上能搜索到的,这其实也是正常的处理逻辑。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">默认情况下 ES 每秒生成一个 segment 文件,当达到一定阈值的时候 会执行merge,merge 过程发生在 JVM中,频繁的生成 Segmen 文件可能会导致频繁的触发 FGC,导致 OOM。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">为了避免避免这种情况,通常采取的手段是降低 segment 文件的生成频率,手段有两个</span> </section> <ul data-sourcepos="1206:1-1208:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">一个是 增加时间阈值,</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">另一个是增大 Buffer的空间阈值,因为缓冲区写满也会生成 Segment 文件。</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">生产经常面临的写入可以分为两种情况:</span> </section> <ul data-sourcepos="1211:1-1217:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">高频低量:高频的创建或更新索引或文档一般发生在 处理 C 端业务的场景下。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">低频高量:一般情况为定期重建索引或批量更新文档数据。</span> </section></li> </ul> <h3 data-sourcepos="1218:1-1218:31" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">4.3.1 写入优化的目标</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">写入调优均,常常以提升写入吞吐量和并发能力为目标,而非提升写入实时性。</span> </section> <h3 data-sourcepos="1222:1-1222:38" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">4.3.2.增加 flush 时间间隔,</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">目的是减小数据写入磁盘的频率,减小磁盘IO频率。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在 Elasticsearch 中,</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">flush</span></code> <span style="font-size: 15px;">操作主要是将索引缓冲区(Index Buffer)中的数据刷新到磁盘上的索引文件中。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">当新的数据写入 Elasticsearch 时,会先存储在内存的索引缓冲区中。</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">flush</span></code> <span style="font-size: 15px;">操作会将这些缓冲区中的数据持久化,以确保数据的安全性和可恢复性。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">同时,</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">flush</span></code> <span style="font-size: 15px;">操作还会更新索引的相关元数据,如提交点(Commit Point)等。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>通过配置文件修改flush时间间隔</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在 Elasticsearch 的</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">elasticsearch.yml</span></code> <span style="font-size: 15px;">配置文件中,可以找到与</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">flush</span></code> <span style="font-size: 15px;">相关的参数。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">主要参数是</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">index.translog.flush_threshold_period</span></code> <span style="font-size: 15px;">,它用于控制</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">flush</span></code> <span style="font-size: 15px;">的时间间隔。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这个参数的默认值是</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">30s</span></code> <span style="font-size: 15px;">,表示每隔 30 秒会自动进行一次</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">flush</span></code> <span style="font-size: 15px;">操作。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">修改时间间隔要增加flush时间间隔,例如将其设置为60s,可以在elasticsearch.yml配置文件中添加或修改以下内容:</span> </section> <pre data-sourcepos="1244:1-1246:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;"><span style="color: rgb(1, 86, 146);">index.translog.flush_threshold_period:</span> <span style="color: rgb(84, 121, 13);">60s</span><br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">修改完成后,保存配置文件并重启 Elasticsearch 服务,新的</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">flush</span></code> <span style="font-size: 15px;">时间间隔就会生效。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">尼恩提示,增加</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">flush</span></code> <span style="font-size: 15px;">时间间隔意味着数据在内存缓冲区中停留的时间更长。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">如果在这段时间内发生服务器故障或 Elasticsearch 进程意外终止,可能会导致缓冲区中的数据丢失。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">因此,在增加</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">flush</span></code> <span style="font-size: 15px;">时间间隔的同时,需要权衡数据安全性和性能之间的关系。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">如果数据的可靠性要求极高,不建议过长地延长</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">flush</span></code> <span style="font-size: 15px;">时间间隔。</span> </section> <h3 data-sourcepos="1262:1-1262:46" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">4.3.3 增加refresh_interval的参数值</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在 Elasticsearch 中,</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">refresh_interval</span></code> <span style="font-size: 15px;">是一个用于控制索引数据可见性的重要参数。它定义了索引数据被刷新(Refresh)的时间间隔。当新的数据写入索引后,并不是立即可以被搜索到,而是要等待索引被刷新。刷新操作会使新写入的数据对搜索可见。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">具体来说,Elasticsearch 会在内存中维护一个数据结构来存储索引数据,这个数据结构在刷新之前是不断更新的。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">refresh 刷新操作, 会将这个内存中的数据结构更新到磁盘上的索引文件(倒排索引等)中,并且更新相关的搜索视图,使得新数据能够被查询到。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">增加</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">refresh_interval</span></code> <span style="font-size: 15px;">的参数值 目的,是减少segment文件的创建,减少segment的merge次数,merge是发生在jvm中的,有可能导致full GC,增加refresh会降低搜索的实时性。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">ES的 refresh 行为非常昂贵,并且在正在进行的索引活动时经常调用,会降低索引速度。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>refresh_interval的默认值和取值范围</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>默认值</strong>:默认的</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">refresh_interval</span></code> <span style="font-size: 15px;">是</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">1s</span></code> <span style="font-size: 15px;">。这意味着每隔 1 秒,索引会被刷新一次,新写入的数据会在 1 秒后对搜索可见。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>取值范围</strong>:可以设置为一个时间值,如</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">-1</span></code> <span style="font-size: 15px;">(表示禁用自动刷新,需要手动刷新)、</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">30s</span></code> <span style="font-size: 15px;">、</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">1m</span></code> <span style="font-size: 15px;">等。时间单位可以是秒(</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">s</span></code> <span style="font-size: 15px;">)、分钟(</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">m</span></code> <span style="font-size: 15px;">)、小时(</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">h</span></code> <span style="font-size: 15px;">)等。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">默认情况下,Elasticsearch 每秒(1s ) 定期刷新索引,但仅在最近 30 秒内收到一个或多个搜索请求的索引上。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">如果没有搜索流量或搜索流量很少(例如每 5 分钟不到一个搜索请求), 并且想要优化索引速度,这是最佳配置。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">此行为旨在在不执行搜索的默认情况下自动优化批量索引。建议显式配置此配置项,如 30秒。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">如何修改refresh_interval? 通过配置文件修改,在elasticsearch.yml配置文件中,可以通过添加或修改以下内容来设置refresh_interval</span> </section> <pre data-sourcepos="1294:1-1296:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;"><span style="color: rgb(1, 86, 146);">index.refresh_interval:</span> <span style="color: rgb(84, 121, 13);">30s</span><br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这会将所有新创建的索引的刷新间隔设置为 30 秒。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">如果只想对特定的现有索引进行设置,可以使用索引设置 API。发送一个 PUT 请求到</span> </section> <pre data-sourcepos="1302:1-1304:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">http://<es - node - ip>:9200/<index - name>/_settings<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">,其中<index - name>是要修改的索引名称。请求体如下:</span> </section> <pre data-sourcepos="1310:1-1316:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">{<br> <span style="color: rgb(1, 86, 146);">"index"</span>: {<br> <span style="color: rgb(1, 86, 146);">"refresh_interval"</span>: <span style="color: rgb(84, 121, 13);">"30s"</span><br> }<br>}<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这种方式可以在不重启 Elasticsearch 的情况下,动态地修改特定索引的刷新间隔。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">延长</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">refresh_interval</span></code> <span style="font-size: 15px;">可以提高索引的写入性能。因为刷新操作是一个相对较重的操作,它涉及到内存数据结构到磁盘索引的更新以及搜索视图的更新。减少刷新频率可以减少磁盘 I/O 和 CPU 的消耗,使得更多的资源可以用于数据写入。例如,在大数据量的批量写入场景下,将</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">refresh_interval</span></code> <span style="font-size: 15px;">延长到 30 秒或更长,可以显著提高写入速度。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">但是,延长</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">refresh_interval</span></code> <span style="font-size: 15px;">会导致新数据对搜索可见的延迟增加。如果应用场景对数据的实时性要求很高,如实时搜索系统,可能需要谨慎考虑延长刷新间隔的影响。</span> </section> <h3 data-sourcepos="1324:1-1324:51" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">4.3.4 写入的时候, 增加Buffer大小<span style="display: none;line-height: 0px;"></span></span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">本质也是减小refresh的时间间隔,因为导致segment文件创建的原因不仅有时间阈值,还有buffer空间大小,写满了也会创建。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">默认最小值 48MB< 默认值 JVM 空间的10% < 默认最大无限制</span> </section> <h3 data-sourcepos="1330:1-1330:41" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">4.3.5 写入的时候, 关闭副本</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">当需要单次写入大量数据的时候,建议关闭副本,暂停搜索服务,或选择在检索请求量谷值区间时间段来完成。</span> </section> <ul data-sourcepos="1334:1-1336:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">第一是减小读写之间的资源抢占,读写分离</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">第二,当检索请求数量很少的时候,可以减少甚至完全删除副本分片,关闭segment的自动创建以达到高效利用内存的目的,因为副本的存在会导致主从之间频繁的进行数据同步,大大增加服务器的资源占用。</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">具体可通过则设置</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">index.number_of_replicas</span></code> <span style="font-size: 15px;"> 为</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">0</span></code> <span style="font-size: 15px;">以加快索引速度。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">没有副本意味着丢失单个节点可能会导致数据丢失,因此数据保存在其他地方很重要,以便在出现问题时可以重试初始加载。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">初始加载完成后,可以设置</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">index.number_of_replicas</span></code> <span style="font-size: 15px;">改回其原始值。</span> </section> <h2 data-sourcepos="1347:1-1347:26" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top-width: 1px;border-top-style: solid;border-top-color: rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">4.4 数据分片设置</span></h2> <h3 data-sourcepos="1351:1-1351:32" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">4.4.1 数据分片的预估</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">ES一旦创建好索引后,就无法调整分片的设置,而在ES中,一个分片实际上对应一个lucene 索引,而lucene索引的读写会占用很多的系统资源,因此,分片数不能设置过大;</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">所以,在创建索引时,合理配置分片数是非常重要的。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">一般来说,我们遵循一些原则:</span> </section> <ol data-sourcepos="1359:1-1376:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">控制每个分片占用的硬盘容量,不超过ES的最大JVM的堆空间设置(一般设置不超过32G,参加上文的JVM设置原则),</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">因此,如果索引的总容量在500G左右,那分片大小在16个左右即可。</span> </section></li> <li style="margin-top: 0.25em;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">一般都设置分片数不超过节点数的3倍。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">考虑一下node数量,一般一个节点有时候就是一台物理机,如果分片数过多,大大超过了节点数,很可能会导致一个节点上存在多个分片,</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">一旦该节点故障,即使保持了1个以上的副本,同样有可能会导致数据丢失,集群无法恢复。</span> </section> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">所以, 一般都设置分片数不超过节点数的3倍。</span> </section></li> </ol> <h3 data-sourcepos="1377:1-1377:29" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">4.4.2 分片分配策略</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">ES使用数据分片(shard)来提高服务的可用性,将数据分散保存在不同的节点上以降低当单个节点发生故障时对数据完整性的影响,同时使用副本(repiica)来保证数据的完整性。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">关于分片的默认分配策略,在7.x之前,默认5个primary shard,每个primary shard默认分配一个replica,即5主1副,而7.x之后,默认1主1副</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">ES的 分片分配策略,大致如下:</span> </section> <ul data-sourcepos="1385:1-1389:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">ES在分配单个索引的分片时会将每个分片尽可能分配到更多的节点上。但是,实际情况取决于集群拥有的分片和索引的数量以及它们的大小,不一定总是能均匀地分布。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">Paimary只能在索引创建时配置数量,而replica可以在任何时间分配,并且primary支持读和写操作,而replica只支持客户端的读取操作,数据由es自动管理,从primary同步。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">ES不允许Primary和它的Replica放在同一个节点中,并且同一个节点不接受完全相同的两个Replica</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">同一个节点允许多个索引的分片同时存在。</span> </section></li> </ul> <h3 data-sourcepos="1390:1-1390:25" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">4.4.3 分片的数量</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>避免分片过多</strong>:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">大多数搜索会命中多个分片。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">每个分片在单个 CPU 线程上运行搜索。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">虽然分片可以运行多个并发搜索,但跨大量分片的</span> <span style="font-size: 15px;">搜索</span> <span style="font-size: 15px;">会耗尽节点的</span> <span style="font-size: 15px;">搜索线程池</span> <span style="font-size: 15px;">。这会导致低吞吐量和缓慢的搜索速度。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>分片越少越好</strong>:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">每个分片都使用内存和 CPU 资源。在大多数情况下,一小组大分片比许多小分片使用更少的资源。</span> </section> <h3 data-sourcepos="1404:1-1404:31" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">4.4.4 分片的大小决策</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>分片的合理容量</strong>:10GB-50GB。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">虽然不是硬性限制,但 10GB 到 50GB 之间的分片往往效果很好。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">根据网络和用例,也许可以使用更大的分片。在索引的生命周期管理中,一般设置50GB为单个索引的最大阈值。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>堆内存容量和分片数量的关联</strong>:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">小于20分片/每GB堆内存,一个节点可以容纳的分片数量与节点的堆内存成正比。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,一个拥有 30GB 堆内存的节点最多应该有 600 个分片。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">如果节点超过每 GB 20 个分片,考虑添加另一个节点。</span> </section> <h1 data-sourcepos="1424:1-1424:40" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top-width: 1px;border-top-style: solid;border-top-color: rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">5 ElasticSearch 索引层面的优化</span></h1> <h3 data-sourcepos="1428:1-1428:37" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">5.1. 避免使用 dynamic mapping</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">尽量避免使用 dynamic mapping,即不要让 Elasticsearch 自动根据新插入的数据来推测字段类型并创建映射。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">而是在创建索引时,提前明确地定义好每个字段的类型、属性(如是否存储、是否索引、分词器等)。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这样可以避免因数据类型不一致导致的索引混乱和性能问题,同时也能更好地控制索引的结构和资源占用。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,在一个用户信息索引中,明确指定用户的年龄字段为</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">integer</span></code> <span style="font-size: 15px;">类型,姓名字段为</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">text</span></code> <span style="font-size: 15px;">类型并设置合适的分词器,而不是依赖 Elasticsearch 自动判断。</span> </section> <h3 data-sourcepos="1440:1-1440:45" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">5.2. 合理设置 doc_values 和 fielddata</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>doc_values定义与概念</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">doc_values 是 Elasticsearch 中一种用于存储正排索引的数据结构。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">它是在索引构建阶段就被创建并存储在磁盘上的,主要用于快速地基于字段进行排序、聚合和脚本计算等操作。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">当执行这些操作时,Elasticsearch 会从磁盘读取 doc_values 数据,而不需要重新解析原始的文档源(_source)数据,这大大提高了这些操作的效率。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>doc_values工作原理</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">对于每个文档中的字段,doc_values 会以一种列式存储的方式记录其数据。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,对于一个包含 “姓名” 和 “年龄” 字段的文档集合,doc_values 会分别存储所有文档的 “姓名” 列和 “年龄” 列的数据。这种列式存储结构在进行排序和聚合操作时非常高效,因为它可以快速地遍历和处理同一列的数据。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">当进行排序操作时,比如按照年龄从小到大排序,Elasticsearch 可以直接从 doc_values 中读取年龄列的数据,然后进行排序,而不需要逐个文档去解析获取年龄信息。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">同样,在进行聚合操作(如计算年龄的平均值、统计不同姓名的数量等)时,doc_values 提供了一种高效的数据访问方式,使得这些操作能够快速完成。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>doc_values适用场景和优势</strong></span> </section> <ul data-sourcepos="1464:1-1467:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;"><strong>排序操作</strong>:当需要对字段进行排序时,doc_values 的优势明显。例如,在电商产品搜索中,按照价格、销量等字段排序,或者在日志分析中按照时间戳排序,doc_values 能够快速提供排序所需的数据,提高排序效率。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;"><strong>聚合操作</strong>:对于统计计算(如求和、平均值、最大值、最小值等)和分组聚合(如统计不同类别产品的数量、不同时间段内日志的数量等),doc_values 是必不可少的。它允许 Elasticsearch 快速访问字段数据,而不需要在内存中重新构建数据结构。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;"><strong>脚本计算</strong>:在使用脚本进行数据处理时,如果脚本涉及到对字段的访问和操作,doc_values 可以提供高效的数据获取方式,提高脚本执行的速度。</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>关闭不需要的doc_values</strong> </span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">对于不需要进行聚合操作的字段,在索引映射(Mapping)中设置</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">"doc_values": false</span></code> <span style="font-size: 15px;">,以节省磁盘空间和资源消耗,提高查询速度。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,对于一些仅用于存储但不参与聚合计算的日志时间戳字段,如果不需要对时间戳进行统计分析等聚合操作,就可以关闭其 doc_values。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">当创建一个新的索引时,可以在索引映射中明确指定哪些字段不需要 doc_values。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,假设要创建一个名my_index的索引,其中包含title(文章标题)和content(文章内容)两个字段,且content字段不需要 doc_values,因为这个字段主要用于全文搜索,很少用于排序或聚合等操作。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">可以使用以下的索引映射定义来关闭content字段的 doc_values:</span> </section> <pre data-sourcepos="1480:1-1496:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">PUT /my_index<br>{<br> <span style="color: rgb(1, 86, 146);">"mappings"</span>: {<br> <span style="color: rgb(1, 86, 146);">"properties"</span>: {<br> <span style="color: rgb(1, 86, 146);">"title"</span>: {<br> <span style="color: rgb(1, 86, 146);">"type"</span>: <span style="color: rgb(84, 121, 13);">"text"</span>,<br> <span style="color: rgb(1, 86, 146);">"doc_values"</span>: <span style="color: rgb(183, 85, 1);">true</span><br> },<br> <span style="color: rgb(1, 86, 146);">"content"</span>: {<br> <span style="color: rgb(1, 86, 146);">"type"</span>: <span style="color: rgb(84, 121, 13);">"text"</span>,<br> <span style="color: rgb(1, 86, 146);">"doc_values"</span>: <span style="color: rgb(183, 85, 1);">false</span><br> }<br> }<br> }<br>}<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>fielddata定义与概念</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">fielddata 是一种在内存中缓存的数据结构,主要用于支持对文本类型字段(text 类型)的聚合操作。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">fielddata 与 doc_values 不同,fielddata 是在运行时(runtime)构建的,并且存储在 JVM 堆内存中。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">fielddata 的目的是为了弥补 text 类型字段在默认情况下无法进行聚合操作的不足。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>fielddata工作原理</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">当对 text 类型字段进行聚合操作时,Elasticsearch 会将该字段的所有词项(terms)加载到 fielddata 缓存中。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,对于一个包含产品描述的 text 字段,当需要统计不同关键词在产品描述中出现的频率时,Elasticsearch 会先将产品描述中的所有词汇加载到 fielddata 缓存中,然后进行统计计算。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">fielddata 的构建是一个相对昂贵的过程,它需要对文本进行分词处理,并将分词后的结果存储在内存中。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">而且,由于它存储在 JVM 堆内存中,对于大量的文本数据进行聚合操作时,可能会导致内存占用过大,甚至出现内存溢出(OOM)的情况。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>谨慎使用 fielddata</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">谨慎使用 fielddata,因为它会占用大量的 JVM 堆内存空间。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">如果确实需要对某个字段进行聚合操作,且该字段数据量较大,考虑提前规划好 JVM 内存设置,防止出现 OutOfMemoryError(OOM)。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">同时,尽量避免在高并发或大数据量聚合场景下频繁使用 fielddata。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,对于一个电商商品搜索索引中的商品描述字段,如果只是偶尔进行简单的关键词搜索,而几乎不会对该字段进行聚合操作,那么就不要开启 fielddata。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>创建新索引时关闭 fielddata</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">当创建新索引时,可以在映射中指定字段的属性来控制 fielddata 的开启或关闭。假设创建一个名为new_index</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">的索引,包含product_name(产品名称)和product_description(产品描述)两个字段,且不想为这些字段开启 fielddata(因为这些字段主要用于搜索,而非复杂的文本聚合),可以按照以下方式定义索引映射:</span> </section> <pre data-sourcepos="1538:1-1554:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">PUT /new_index<br>{<br> <span style="color: rgb(1, 86, 146);">"mappings"</span>: {<br> <span style="color: rgb(1, 86, 146);">"properties"</span>: {<br> <span style="color: rgb(1, 86, 146);">"product_name"</span>: {<br> <span style="color: rgb(1, 86, 146);">"type"</span>: <span style="color: rgb(84, 121, 13);">"text"</span>,<br> <span style="color: rgb(1, 86, 146);">"fielddata"</span>: <span style="color: rgb(183, 85, 1);">false</span><br> },<br> <span style="color: rgb(1, 86, 146);">"product_description"</span>: {<br> <span style="color: rgb(1, 86, 146);">"type"</span>: <span style="color: rgb(84, 121, 13);">"text"</span>,<br> <span style="color: rgb(1, 86, 146);">"fielddata"</span>: <span style="color: rgb(183, 85, 1);">false</span><br> }<br> }<br> }<br>}<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>启用特定聚合功能但不使用 fielddata</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">对于一些文本字段,如果需要进行简单的聚合操作,如统计不同词条的文档计数(这是一种比较常见的聚合场景),可以考虑使用keyword类型来代替text类型。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,对于一个category(产品类别)字段,如果只想统计不同类别产品的数量,将其定义为keyword类型而不是text类型,就不需要开启 fielddata 来进行聚合操作。</span> </section> <pre data-sourcepos="1564:1-1576:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">PUT /new_index<br>{<br> <span style="color: rgb(1, 86, 146);">"mappings"</span>: {<br> <span style="color: rgb(1, 86, 146);">"properties"</span>: {<br> <span style="color: rgb(1, 86, 146);">"category"</span>: {<br> <span style="color: rgb(1, 86, 146);">"type"</span>: <span style="color: rgb(84, 121, 13);">"keyword"</span>,<br> <span style="color: rgb(1, 86, 146);">"fielddata"</span>: <span style="color: rgb(183, 85, 1);">false</span><br> }<br> }<br> }<br>}<br></span> </section></pre> <h3 data-sourcepos="1580:1-1580:35" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">5.3. 优化 ignore_above 设置</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">对于字符串类型的字段,根据业务需求合理设置</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">ignore_above</span></code> <span style="font-size: 15px;">参数。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">该参数指定了字符串字段的最大长度,超过此长度的文本将被忽略。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">将其设置得越小越好,但要确保不会丢失重要的业务数据。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,在一个商品评论索引中,如果业务只关心评论的前 100 个字符用于搜索和分析,那么可以将评论内容字段的</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">ignore_above</span></code> <span style="font-size: 15px;">设置为 100,这样可以减少索引的大小和资源消耗,同时提高查询性能。</span> </section> <h3 data-sourcepos="1594:1-1594:30" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">5.4. 调整 _source 字段</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">通过</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">_source</span></code> <span style="font-size: 15px;">字段的</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">include</span></code> <span style="font-size: 15px;">和</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">exclude</span></code> <span style="font-size: 15px;">参数来精细控制哪些字段需要存储在</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">_source</span></code> <span style="font-size: 15px;">中。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">只保留对业务查询和显示有必要的字段,避免存储过多不必要的字段数据,以节省磁盘空间和网络带宽。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,在一个新闻文章索引中,如果业务只需要在搜索结果中展示文章标题、发布时间和正文的前 200 个字符,那么可以使用</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">"_source": {"includes": ["title", "publish_time", "body.substring(0,200)"]}</span></code> <span style="font-size: 15px;">来配置</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">_source</span></code> <span style="font-size: 15px;">字段,排除其他不需要的字段。</span> </section> <h3 data-sourcepos="1606:1-1606:34" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">5.5. 谨慎使用 store 属性</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">对于一些需要频繁访问但又不想每次都从</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">_source</span></code> <span style="font-size: 15px;">中提取的字段,可以考虑使用</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">store</span></code> <span style="font-size: 15px;">属性为其开辟单独的存储空间。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这样在查询时可以直接从存储的字段中获取数据,而无需解析</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">_source</span></code> <span style="font-size: 15px;">,从而节省网络带宽和查询时间。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">但要注意,过多地使用</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">store</span></code> <span style="font-size: 15px;">属性会增加磁盘空间的占用,所以需要根据字段的访问频率和重要性进行权衡。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,对于一个经常需要在搜索结果中单独展示的商品图片 URL 字段,可以设置</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">"store": true</span></code> <span style="font-size: 15px;">,以便快速获取该字段的值。</span> </section> <h3 data-sourcepos="1620:1-1620:45" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">5.6. 关于禁用 _source 字段的考虑</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">虽然禁用_source字段可以节省大量磁盘空间,但在决定禁用之前,必须充分考虑其带来的后果:</span> </section> <ul data-sourcepos="1626:1-1631:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">由于</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">update</span></code> <span style="font-size: 15px;">、</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">update_by_query</span></code> <span style="font-size: 15px;">和</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">reindex</span></code> <span style="font-size: 15px;">操作都依赖于</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">_source</span></code> <span style="font-size: 15px;">字段,禁用后这些操作将不可用。如果业务可能需要对索引数据进行更新或重新索引,那么禁用</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">_source</span></code> <span style="font-size: 15px;">字段可能会带来不便。</span> </section></li> <li style="margin-top: 0.25em;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">禁用</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">_source</span></code> <span style="font-size: 15px;">字段会导致高亮显示功能失效,因为高亮显示通常是基于</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">_source</span></code> <span style="font-size: 15px;">中的原始文本进行的。如果搜索结果需要高亮显示匹配的关键词,那么禁用</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">_source</span></code> <span style="font-size: 15px;">字段就不适合。</span> </section></li> <li style="margin-top: 0.25em;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">禁用</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">_source</span></code> <span style="font-size: 15px;">字段会影响索引的容灾能力,因为在数据丢失或损坏的情况下,没有</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">_source</span></code> <span style="font-size: 15px;">字段将难以恢复原始数据。因此,除非对磁盘空间有极其严格的限制,并且确定上述功能在业务中几乎不会用到,否则不建议轻易禁用</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">_source</span></code> <span style="font-size: 15px;">字段。</span> </section></li> </ul> <h3 data-sourcepos="1632:1-1632:26" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">5.7. 禁用 all 字段</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在 Elasticsearch 6.0 及以上版本中,</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">all</span></code> <span style="font-size: 15px;">字段默认是关闭的。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">如果使用的是早期版本,且确定不需要在搜索时从所有字段中进行模糊检索(即不使用未指定字段名的搜索),那么可以手动关闭</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">all</span></code> <span style="font-size: 15px;">字段,以节省磁盘空间和提高索引创建速度。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,在一个结构化数据索引中,每个字段的用途都很明确,很少会进行跨所有字段的模糊搜索,此时关闭</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">all</span></code> <span style="font-size: 15px;">字段是一个优化选择。</span> </section> <h3 data-sourcepos="1644:1-1644:32" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">5.8. 关闭 Norms 字段</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">对于那些确定不需要用于计算文档相关性评分(如在过滤查询和聚合操作中使用的字段),在索引映射中设置</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">"norms": false</span></code> <span style="font-size: 15px;">。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这样可以节省大量的磁盘空间,尤其是对于那些包含大量文本的字段。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,在一个日志索引中,对于日志级别、IP 地址等字段,这些字段通常只用于过滤查询而不需要计算评分,将其</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">norms</span></code> <span style="font-size: 15px;">字段关闭可以优化索引性能。</span> </section> <h3 data-sourcepos="1656:1-1656:53" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">5.9. 谨慎关闭 index_options(高端操作)</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">index_options</span></code> <span style="font-size: 15px;">参数控制着在索引创建过程中哪些信息会被添加到倒排索引文件中,如词频(TF)、文档频率(docCount)、位置(postion)、偏移量(offsets)等。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">减少这些选项可以降低索引创建时的 CPU 占用率,但需要谨慎操作。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">因为在实际业务中,很难预先确定将来是否会用到这些信息。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">除非在创建索引之前,对业务需求有非常清晰的了解,并且确定某些信息绝对不会被使用,否则不建议随意关闭</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">index_options</span></code> <span style="font-size: 15px;">中的选项,以免影响后续的查询功能和准确性。</span> </section> <h3 data-sourcepos="1670:1-1670:37" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">5.10. 合理设置 enabled 属性</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">对于那些不需要进行查询操作的字段,在索引映射中设置</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">"enabled": false</span></code> <span style="font-size: 15px;">,以避免创建不必要的倒排索引,从而节省磁盘空间和资源消耗。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,在一个只用于数据存储和备份的索引中,某些仅用于记录内部标识或辅助信息的字段,如果不需要对其进行搜索查询,就可以将其设置为</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">enabled</span></code> <span style="font-size: 15px;">为</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">false</span></code> <span style="font-size: 15px;">。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在实施上述优化方案时,需要根据具体的业务需求、数据特点和硬件资源进行综合考虑和调整,并且在优化前后进行充分的性能测试,以确保优化措施能够有效地提高 Elasticsearch 索引的性能和资源利用率。同时,随着业务的发展和数据的变化,可能需要定期对索引进行重新评估和优化,以维持良好的性能表现。</span> </section> <h3 data-sourcepos="1686:1-1686:35" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">5.11. max_result_window参数</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">max_result_window是分页返回的最大数值,默认值为10000。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">max_result_window本身是对JVM的一种保护机制,通过设定一个合理的阈值,避免初学者分页查询时由于单页数据过大而导致OOM。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在很多业务场景中经常需要查询10000条以后的数据,当遇到不能查询10000条以后的数据的问题之后,网上的很多答案会告诉你可以通过放开这个参数的限制,将其配置为100万,甚至1000万就行。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">但是如果仅仅放开这个参数就行,那么这个参数限制的意义有何在呢?</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">如果你不知道这个参数的意义,很可能导致的后果就是频繁的发生OOM而且很难找到原因,设置一个合理的大小是需要通过你的各项指标参数来衡量确定的,比如你用户量、数据量、物理内存的大小、分片的数量等等。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">通过监控数据和分析各项指标从而确定一个最佳值,并非越大越好</span> </section> <h2 data-sourcepos="1704:1-1704:41" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top-width: 1px;border-top-style: solid;border-top-color: rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">6 ElasticSearch查询层面的优化</span></h2> <h4 data-sourcepos="1710:1-1710:35" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">避免使用稀疏数据</span></h4> <ul data-sourcepos="1718:1-1721:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li> <section style="line-height: 1.75em;"> <span style="caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";font-size: 15px;letter-spacing: normal;text-align: start;">查询调优</span> <br> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">索引时间精度优化</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">研究Filter的工作原理可以看出,它每次工作都是遍历整个索引的,所以时间粒度越大,对比越快,搜索时间越短,在不影响功能的情况下,时间精度越低越好,有时甚至牺牲一点精度也值得,当然最好的情况是根本不作时间限制。 es重新刷索引,增加冗余的时间字段,精确到天。带有时间范围的查询使用该字段进行查询</span> </section> <ul data-sourcepos="1725:1-1726:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">查询Fetch Source优化</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">业务查询语句获取的数据集比较大,并且从source中获取了非必须的字段,导致查询较慢。 举例:只需要从es中查询id这一个字段,却把所有字段查询了出来</span> </section> <ul data-sourcepos="1730:1-1731:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">‘数据预索引’查询优化</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">数据预索引查询优化是一种在Elasticsearch中通过预先处理和索引数据来提高查询性能的技术。这种方法的核心思想是识别查询中的常见模式,并根据这些模式来优化数据的索引方式,从而加快查询速度。</span> </section> <h3 data-sourcepos="1736:1-1736:55" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">6.1 调整filter过滤顺序, 过滤优先原则</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">问题:</span> </section> <ul data-sourcepos="1740:1-1745:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">如果把全文查询(如</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">match</span></code> <span style="font-size: 15px;">)的条件放在了前面,导致命中不了缓存,导致查询变慢。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="margin-top: 16px;margin-bottom: 16px;line-height: 1.75em;"> <span style="font-size: 15px;">如果把过滤效果不明显的条件放在了前面,导致查询出大量不需要的数据,导致查询变慢。</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在Elasticsearch中,查询优化的一个关键方面是正确使用过滤器(filters)和查询(queries)。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">过滤器(如</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">term</span></code> <span style="font-size: 15px;">、</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">range</span></code> <span style="font-size: 15px;">等)通常比全文查询(如</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">match</span></code> <span style="font-size: 15px;">) 更快,为啥呢?</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">因为 filters 可以被缓存,而全文查询(如</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">match</span></code> <span style="font-size: 15px;">)则不可以被缓存。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">因此,调整过滤器和查询的顺序,优先使用过滤器,可以显著提高查询性能。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">以下是一个使用Elasticsearch查询DSL的例子,展示了如何通过调整</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">filter</span></code> <span style="font-size: 15px;">和</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">query</span></code> <span style="font-size: 15px;">的顺序来优化查询:</span> </section> <h4 data-sourcepos="1756:1-1756:23" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">未优化的查询</span></h4> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">假设我们有一个商品索引,包含商品的名称(</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">name</span></code> <span style="font-size: 15px;">)、价格(</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">price</span></code> <span style="font-size: 15px;">)和分类(</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">category</span></code> <span style="font-size: 15px;">)字段。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">一个未优化的查询可能如下:</span> </section> <pre data-sourcepos="1764:1-1793:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">GET /products/_search<br>{<br> <span style="color: rgb(1, 86, 146);">"query"</span>: {<br> <span style="color: rgb(1, 86, 146);">"bool"</span>: {<br> <span style="color: rgb(1, 86, 146);">"must"</span>: [<br> {<br> <span style="color: rgb(1, 86, 146);">"match"</span>: {<br> <span style="color: rgb(1, 86, 146);">"name"</span>: <span style="color: rgb(84, 121, 13);">"apple"</span><br> }<br> }<br> ],<br> <span style="color: rgb(1, 86, 146);">"filter"</span>: [<br> {<br> <span style="color: rgb(1, 86, 146);">"term"</span>: {<br> <span style="color: rgb(1, 86, 146);">"category"</span>: <span style="color: rgb(84, 121, 13);">"fruit"</span><br> }<br> },<br> {<br> <span style="color: rgb(1, 86, 146);">"range"</span>: {<br> <span style="color: rgb(1, 86, 146);">"price"</span>: {<br> <span style="color: rgb(1, 86, 146);">"lte"</span>: <span style="color: rgb(183, 85, 1);">100</span><br> }<br> }<br> }<br> ]<br> }<br> }<br>}<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在这个查询中,我们首先使用</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">match</span></code> <span style="font-size: 15px;">查询来搜索名称中包含“apple”的商品,然后使用</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">filter</span></code> <span style="font-size: 15px;">来过滤属于“fruit”分类且价格不超过100的商品。</span> </section> <h4 data-sourcepos="1797:1-1797:23" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">优化后的查询</span></h4> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">如何优化这个查询?</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">可以将</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">filter</span></code> <span style="font-size: 15px;">条件移到</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">must</span></code> <span style="font-size: 15px;">子句中,因为</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">filter</span></code> <span style="font-size: 15px;">可以被缓存,这样可以减少需要检查的文档数量,从而提高查询效率:</span> </section> <pre data-sourcepos="1805:1-1838:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">GET /products/_search<br>{<br> <span style="color: rgb(1, 86, 146);">"query"</span>: {<br> <span style="color: rgb(1, 86, 146);">"bool"</span>: {<br> <span style="color: rgb(1, 86, 146);">"must"</span>: [<br> {<br> <span style="color: rgb(1, 86, 146);">"bool"</span>: {<br> <span style="color: rgb(1, 86, 146);">"filter"</span>: [<br> {<br> <span style="color: rgb(1, 86, 146);">"term"</span>: {<br> <span style="color: rgb(1, 86, 146);">"category"</span>: <span style="color: rgb(84, 121, 13);">"fruit"</span><br> }<br> },<br> {<br> <span style="color: rgb(1, 86, 146);">"range"</span>: {<br> <span style="color: rgb(1, 86, 146);">"price"</span>: {<br> <span style="color: rgb(1, 86, 146);">"lte"</span>: <span style="color: rgb(183, 85, 1);">100</span><br> }<br> }<br> }<br> ]<br> }<br> },<br> {<br> <span style="color: rgb(1, 86, 146);">"match"</span>: {<br> <span style="color: rgb(1, 86, 146);">"name"</span>: <span style="color: rgb(84, 121, 13);">"apple"</span><br> }<br> }<br> ]<br> }<br> }<br>}<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在这个优化后的查询中,我们首先使用</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">bool</span></code> <span style="font-size: 15px;">查询的</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">filter</span></code> <span style="font-size: 15px;">子句来过滤出属于“fruit”分类且价格不超过100的商品,然后再使用</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">match</span></code> <span style="font-size: 15px;">查询来搜索名称中包含“apple”的商品。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这样,</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">match</span></code> <span style="font-size: 15px;">查询只需要在已经过滤过的文档集上运行,从而提高了查询效率。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">通过这种方式,我们可以确保使用过滤器来减少搜索空间,然后再应用全文查询,这样可以显著提高查询性能,尤其是在处理大量数据时。</span> </section> <h3 data-sourcepos="1850:1-1850:30" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">6.2 使用 Keyword 类型</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">ES中,并非所有数值数据都应映射为数值字段数据类型,</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">Elasticsearch为 数值数据提供了 查询优化 ,例如</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">integer</span></code> <span style="font-size: 15px;"> 、 long。 如果不需要范围查找,对于 term查询而言,keyword 比 integer 性能更好。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">假设一个电商产品索引,其中包含产品 ID(</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">product_id</span></code> <span style="font-size: 15px;">)和产品价格(</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">price</span></code> <span style="font-size: 15px;">)两个字段。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">产品 ID 是一个唯一标识每个产品的数字,产品价格是实际的价格数值。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">我们将分别比较使用</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">keyword</span></code> <span style="font-size: 15px;">和</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">integer</span></code> <span style="font-size: 15px;">类型来存储产品 ID 在</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">term</span></code> <span style="font-size: 15px;">查询中的性能差异。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">索引创建与数据插入,使用</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">integer</span></code> <span style="font-size: 15px;">类型存储产品 ID 并插入数据</span> </section> <pre data-sourcepos="1864:1-1878:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">PUT /products_index_integer_id<br>{<br> <span style="color: rgb(1, 86, 146);">"mappings"</span>: {<br> <span style="color: rgb(1, 86, 146);">"properties"</span>: {<br> <span style="color: rgb(1, 86, 146);">"product_id"</span>: {<br> <span style="color: rgb(1, 86, 146);">"type"</span>: <span style="color: rgb(84, 121, 13);">"integer"</span><br> },<br> <span style="color: rgb(1, 86, 146);">"price"</span>: {<br> <span style="color: rgb(1, 86, 146);">"type"</span>: <span style="color: rgb(84, 121, 13);">"float"</span><br> }<br> }<br> }<br>}<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">插入一些示例数据,假设有 10000 个产品,产品 ID 从 1 到 10000,价格随机生成在 10.0 到 1000.0 之间。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">尼恩这里省略了过程, 大家可以自己设计一个脚本试一下。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">使用</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">keyword</span></code> <span style="font-size: 15px;">类型存储产品 ID 并插入数据,创建另一个索引 products_index_keyword_id,将产品 ID 字段定义为keyword类型,产品价格字段同样定义为float类型。</span> </section> <pre data-sourcepos="1886:1-1900:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">PUT /products_index_keyword_id<br>{<br> <span style="color: rgb(1, 86, 146);">"mappings"</span>: {<br> <span style="color: rgb(1, 86, 146);">"properties"</span>: {<br> <span style="color: rgb(1, 86, 146);">"product_id"</span>: {<br> <span style="color: rgb(1, 86, 146);">"type"</span>: <span style="color: rgb(84, 121, 13);">"keyword"</span><br> },<br> <span style="color: rgb(1, 86, 146);">"price"</span>: {<br> <span style="color: rgb(1, 86, 146);">"type"</span>: <span style="color: rgb(84, 121, 13);">"float"</span><br> }<br> }<br> }<br>}<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">使用相同的方法插入 10000 个产品数据到这个索引中。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">然后去做 精确匹配(</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">term</span></code> <span style="font-size: 15px;">查询) 的对比测试:</span> </section> <pre data-sourcepos="1906:1-1912:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">"query": {<br> "term": {<br> "product_id": 5000<br> }<br> }<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在多次测试后,你可能会发现,对于</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">term</span></code> <span style="font-size: 15px;">查询产品 ID,使用</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">keyword</span></code> <span style="font-size: 15px;">类型的查询,比int 类型的查询,性能更好。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这是因为</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">keyword</span></code> <span style="font-size: 15px;">类型在存储和查询数据时,内部的数据结构更适合精确匹配(</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">term</span></code> <span style="font-size: 15px;">查询)。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">integer</span></code> <span style="font-size: 15px;">类型在 Elasticsearch 中是作为数值类型存储的,虽然它也支持</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">term</span></code> <span style="font-size: 15px;">查询,但在底层存储和检索机制上,对于这种精确匹配的</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">term</span></code> <span style="font-size: 15px;">查询,会有一些额外的处理开销,比如数值范围的校验等(尽管在这个例子中没有涉及范围查询)。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">而</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">keyword</span></code> <span style="font-size: 15px;">类型就像一个简单的字符串存储结构,当进行</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">term</span></code> <span style="font-size: 15px;">查询时,可以直接通过字符串匹配的方式快速定位到对应的文档,减少了不必要的处理步骤,从而提高了查询性能。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>keyword 和 integer 类型的两大不同:</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">第一个不同:<strong>keyword 和 integer 类型的 数据存储结构差异:</strong></span> </section> <ul data-sourcepos="1926:1-1927:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">keyword 类型:</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">当一个字段被定义为</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">keyword</span></code> <span style="font-size: 15px;">类型时,Elasticsearch 会将其视为一个简单<strong>的字符串</strong>进行存储。在底层,</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">keyword</span></code> <span style="font-size: 15px;">类型的数据存储类似于一个字典结构,其中每个唯一的字符串值都有一个对应的标识符。在进行</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">term</span></code> <span style="font-size: 15px;">查询时,Elasticsearch 直接在这个字典结构中查找给定的字符串,就像在一个键值对集合中查找键一样,这种查找方式非常直接和高效。</span> </section> <ul data-sourcepos="1930:1-1931:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">integer 类型:</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">对于</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">integer</span></code> <span style="font-size: 15px;">类型,Elasticsear<strong>ch 会将其作为数值进行存</strong>储。虽然它也支持</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">term</span></code> <span style="font-size: 15px;">查询,但由于其数值属性,在存储和检索过程中会涉及一些额外的处理。例如,它可能会考虑数值的范围、排序规则等因素,即使在进行简单的</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">term</span></code> <span style="font-size: 15px;">查询时,这些额外的机制也可能会增加查询的处理步骤。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>第二个不同:索引构建和查询优化机制不同:</strong></span> </section> <ul data-sourcepos="1936:1-1937:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">keyword 类型:</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">keyword</span></code> <span style="font-size: 15px;">类型在索引构建过程中主要关注的是字符串的精确匹配。它会为每个不同的字符串值构建一个简单而高效的索引结构,用于快速定位包含该字符串的文档。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">term</span></code> <span style="font-size: 15px;">查询时,Elasticsearch 可以直接利用这个索引结构,通过字符串的哈希值或者其他快速查找方法来定位文档,减少了不必要的计算和比较。</span> </section> <ul data-sourcepos="1942:1-1943:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">integer 类型:</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">对于</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">integer</span></code> <span style="font-size: 15px;">类型,索引构建过程可能会考虑到数值的各种特性,如大小排序、范围划分等。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在进行</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">term</span></code> <span style="font-size: 15px;">查询时,虽然最终也是要找到匹配的数值,但它可能需要经过一些额外的验证步骤,以确保查询的数值符合数值类型的规则。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,它可能会检查数值是否在合理的范围之内,这种额外的检查在</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">term</span></code> <span style="font-size: 15px;">查询这种只需要精确匹配的场景下会增加一定的开销。</span> </section> <h3 data-sourcepos="1952:1-1952:27" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">6.3 避免使用脚本</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">Scripting是Elasticsearch支持的一种专门用于复杂场景下支持自定义编程的强大的脚本功能。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">相对于 DSL 而言,脚本的性能更差,DSL能解决 80% 以上的查询需求,如非必须,尽量避免使用 Script</span> </section> <h3 data-sourcepos="1958:1-1958:38" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">6.4 避免单次召回大量数据</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">搜索引擎最擅长的事情是从海量数据中查询少量相关文档,而非单次检索大量文档。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">非常不建议动辄查询上万数据。如果有这样的需求,建议使用滚动查询</span> </section> <h3 data-sourcepos="1964:1-1964:33" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">6.5 避免单个文档过大</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">鉴于默认</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="color: rgb(0, 122, 255);text-decoration: underline;font-size: 15px;">http.max_content_length</span></code> <span style="font-size: 15px;">设置为 100MB,Elasticsearch 将拒绝索引任何大于该值的文档。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">您可能决定增加该特定设置,但 Lucene 仍然有大约 2GB 的限制。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">即使不考虑硬性限制,大型文档通常也不实用。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">大型文档对网络、内存使用和磁盘造成了更大的压力,即使对于不请求的搜索请求也是如此,</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">_source</span></code> <span style="font-size: 15px;">因为 Elasticsearch</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">_id</span></code> <span style="font-size: 15px;">在所有情况下都需要获取文档的文件系统缓存有效。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">对该文档进行索引可能会占用文档原始大小的倍数的内存量。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">Proximity Search(例如短语查询)和高亮查询也变得更加昂贵,因为它们的成本直接取决于原始文档的大小。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">有时重新考虑信息单元应该是什么是有用的。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,您想让书籍可搜索的事实并不一定意味着文档应该包含整本书。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">使用章节甚至段落作为文档可能是一个更好的主意,然后在这些文档中拥有一个属性来标识它们属于哪本书。这不仅避免了大文档的问题,还使搜索体验更好。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,如果用户搜索两个单词</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">foo</span></code> <span style="font-size: 15px;">and </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">bar</span></code> <span style="font-size: 15px;">,则不同章节之间的匹配可能很差,而同一段落中的匹配可能很好。</span> </section> <h3 data-sourcepos="1986:1-1986:63" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">6.6 单次查询10条文档 好于 10次查询每次一条</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">批量请求将产生比单文档索引请求更好的性能。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">但是每次查询多少文档最佳,不同的集群最佳值可能不同,为了获得批量请求的最佳阈值,建议在具有单个分片的单个节点上运行基准测试。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">首先尝试一次索引 100 个文档,然后是 200 个,然后是 400 个等。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在每次基准测试运行中,批量请求中的文档数量翻倍。当索引速度开始趋于平稳时,就可以获得已达到数据批量请求的最佳大小。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在相同性能的情况下,当大量请求同时发送时,太大的批量请求可能会使集群承受内存压力,因此建议避免每个请求超过几十兆字节。</span> </section> <h3 data-sourcepos="1998:1-1998:47" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">6.7 避免 Nested 内嵌 和 Join 连接</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">很多人会忽略对 Elasticsearch 数据建模的重要性。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">一个特别要注意的是,应避免Nested 内嵌。nested属于object类型的一种,是Elasticsearch中用于复杂类型对象数组的索引操作。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">Elasticsearch没有内部对象的概念,因此,ES在存储复杂类型的时候会把对象的复杂层次结果扁平化为一个键值对列表。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">另外一个特别要注意的是,应避免连接。Nested 可以使查询慢几倍,Join 会使查询慢数百倍。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">两种类型的使用场景应该是:Nested针对字段值为非基本数据类型的时候,而Join则用于 当子文档数量级非常大的时候。</span> </section> <h3 data-sourcepos="2016:1-2016:32" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">6.8 使用filter代替query</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">query和filter的主要区别在: filter是结果导向的而<strong>query</strong>是过程导向。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">query倾向于“当前文档和查询的语句的相关度”而filter倾向于“当前文档和查询的条件是不是相符”。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">即在查询过程中,query是要对查询的每个结果计算相关性得分的,而filter不会。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">另外filter有相应的缓存机制,可以提高查询效率。</span> </section> <h3 data-sourcepos="2026:1-2026:26" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">6.9 避免深度分页</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">避免单页数据过大,可以参考百度或者淘宝的做法。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">es提供两种解决方案 scroll search 和 search after。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">关于深度分页的详细原理,推荐阅读:尼恩的技术自由圈的博客</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">ElasticSearch 深度分页 (史上最全、面试必备)_elasticsearch深度分页-CSDN博客</span> </section> <h3 data-sourcepos="2038:1-2038:56" style="margin: 10px auto 5px;font-weight: bold;font-size: 20px;letter-spacing: 0.578px;white-space: normal;background-color: rgb(252, 252, 252);"><span style="margin-top: -1px;padding: 6px 20px 6px 10px;font-size: 17px;font-weight: normal;display: inline-block;line-height: 1.3;background-color: rgb(212, 224, 250);border-bottom-right-radius: 100px;color: rgb(30, 30, 30);">6.10 预索引: ‘数据预索引’查询优化</span></h3> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">利用查询中的模式来优化数据的索引方式。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如,如果所有文档都有一个</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">price</span></code> <span style="font-size: 15px;">字段,并且大多数查询 range 在固定的范围列表上运行聚合,可以通过将范围预先索引到索引中并使用聚合来加快聚合速度。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">以下是一个基于电商系统中商品销售数据统计的案例,来展示 ElasticSearch 的 数据预索引 的优化方案。</span> </section> <h4 data-sourcepos="2048:1-2048:17" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">案例背景</span></h4> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">一个电商平台,平台上有大量的商品在售卖,每天都会产生众多的销售订单记录。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">我们希望通过 ElasticSearch 对这些销售数据进行分析,以便了解不同年龄段用户的购买行为、商品销量情况等信息。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">在业务需求中,经常需要按照用户的年龄范围来进行聚合查询,例如统计不同年龄区间(如 18 - 25 岁、26 - 35 岁、36 - 45 岁等)内购买各类商品的数量、金额等指标。</span> </section> <h4 data-sourcepos="2056:1-2056:29" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">优化前的查询方式</span></h4> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>优化前的数据结构</strong>:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">销售订单数据以文档的形式存储在 ElasticSearch 索引中,每个文档代表一笔销售订单,包含了多个字段,比如</span> </section> <ul data-sourcepos="2062:1-2069:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li> <section style="line-height: 1.75em;"> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">order_id</span></code> <span style="font-size: 15px;">(订单编号)</span> </section></li> <li style="margin-top: 0.25em;"> <section style="line-height: 1.75em;"> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">product_name</span></code> <span style="font-size: 15px;">(商品名称)</span> </section></li> <li style="margin-top: 0.25em;"> <section style="line-height: 1.75em;"> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">price</span></code> <span style="font-size: 15px;">(商品价格)</span> </section></li> <li style="margin-top: 0.25em;"> <section style="line-height: 1.75em;"> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">user_age</span></code> <span style="font-size: 15px;">(用户年龄)</span> </section></li> <li style="margin-top: 0.25em;"> <section style="line-height: 1.75em;"> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">purchase_date</span></code> <span style="font-size: 15px;">(购买日期)等。</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>优化前的查询操作</strong>:</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">当业务人员想要查看不同年龄区间的商品销售总额时,通常会使用如下的聚合查询语句:</span> </section> <pre data-sourcepos="2076:1-2108:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">{<br> <span style="color: rgb(1, 86, 146);">"size"</span>: <span style="color: rgb(183, 85, 1);">0</span>,<br> <span style="color: rgb(1, 86, 146);">"aggs"</span>: {<br> <span style="color: rgb(1, 86, 146);">"age_ranges"</span>: {<br> <span style="color: rgb(1, 86, 146);">"range"</span>: {<br> <span style="color: rgb(1, 86, 146);">"field"</span>: <span style="color: rgb(84, 121, 13);">"user_age"</span>,<br> <span style="color: rgb(1, 86, 146);">"ranges"</span>: [<br> {<br> <span style="color: rgb(1, 86, 146);">"from"</span>: <span style="color: rgb(183, 85, 1);">18</span>,<br> <span style="color: rgb(1, 86, 146);">"to"</span>: <span style="color: rgb(183, 85, 1);">25</span><br> },<br> {<br> <span style="color: rgb(1, 86, 146);">"from"</span>: <span style="color: rgb(183, 85, 1);">26</span>,<br> <span style="color: rgb(1, 86, 146);">"to"</span>: <span style="color: rgb(183, 85, 1);">35</span><br> },<br> {<br> <span style="color: rgb(1, 86, 146);">"from"</span>: <span style="color: rgb(183, 85, 1);">36</span>,<br> <span style="color: rgb(1, 86, 146);">"to"</span>: <span style="color: rgb(183, 85, 1);">45</span><br> }<br> ]<br> },<br> <span style="color: rgb(1, 86, 146);">"aggs"</span>: {<br> <span style="color: rgb(1, 86, 146);">"total_sales"</span>: {<br> <span style="color: rgb(1, 86, 146);">"sum"</span>: {<br> <span style="color: rgb(1, 86, 146);">"field"</span>: <span style="color: rgb(84, 121, 13);">"price"</span><br> }<br> }<br> }<br> }<br> }<br>}<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">上述查询语句的含义是,按照 </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">user_age</span></code> <span style="font-size: 15px;"> 字段进行范围划分,分成几个指定的年龄区间,</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">然后在每个年龄区间内对商品的价格进行求和聚合,以得到不同年龄区间的商品销售总额。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">可能每天有成千上万笔订单, 随着订单数据量的不断增大,这样频繁地执行范围聚合查询会对 ElasticSearch 集群的性能造成巨大压力</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">结果是:查询响应时间可能会逐渐变长,影响业务人员获取数据的效率。</span> </section> <h4 data-sourcepos="2124:1-2124:38" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">预索引数据查询优化方案</span></h4> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>预聚合数据设计</strong></span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">我们决定在数据写入 ElasticSearch 索引时,就提前对用户年龄进行预聚合处理。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">新增一个字段,比如叫 age_group</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">age_group 的值根据 user_age 字段预先划分好的区间来确定。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">例如:</span> </section> <ul data-sourcepos="2140:1-2145:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">当 </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">user_age</span></code> <span style="font-size: 15px;"> 在 18 - 25 岁之间时,</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">age_group</span></code> <span style="font-size: 15px;"> 的值设为 </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">18-25</span></code> <span style="font-size: 15px;">。</span> </section></li> <li style="margin-top: 0.25em;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">当 </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">user_age</span></code> <span style="font-size: 15px;"> 在 26 - 35 岁之间时,</span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">age_group</span></code> <span style="font-size: 15px;"> 的值设为 </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">26-35</span></code> <span style="font-size: 15px;">,</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">以此类推。</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这样,在数据索引阶段,在将订单数据导入 ElasticSearch 时,添加一段逻辑来判断 </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">user_age</span></code> <span style="font-size: 15px;"> 的值,并设置对应的 </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">age_group</span></code> <span style="font-size: 15px;"> 值。</span> </section> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">比如,我们可以通过 Logstash(或者其他 ETL 工具)在将订单数据导入 ,示例 Logstash 配置片段如下:</span> </section> <pre data-sourcepos="2152:1-2165:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">filter {<br> <span style="color: rgb(1, 86, 146);">if</span> [user_age] >= <span style="color: rgb(183, 85, 1);">18</span> && [user_age] <= <span style="color: rgb(183, 85, 1);">25</span> {<br> mutate {<br> add_field => { <span style="color: rgb(84, 121, 13);">"age_group"</span> => <span style="color: rgb(84, 121, 13);">"18-25"</span> }<br> }<br> } <span style="color: rgb(1, 86, 146);">else</span> <span style="color: rgb(1, 86, 146);">if</span> [user_age] > <span style="color: rgb(183, 85, 1);">25</span> && [user_age] <= <span style="color: rgb(183, 85, 1);">35</span> {<br> mutate {<br> add_field => { <span style="color: rgb(84, 121, 13);">"age_group"</span> => <span style="color: rgb(84, 121, 13);">"26-35"</span> }<br> }<br> }<br> <span style="color: rgb(101, 110, 119);"># 其他年龄区间的判断逻辑依次添加</span><br>}<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;"><strong>优化后的查询操作</strong>: 现在,当业务人员想要查询不同年龄区间的商品销售总额时,就可以使用基于 </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">age_group</span></code> <span style="font-size: 15px;"> 字段的更简单高效的聚合查询语句:</span> </section> <pre data-sourcepos="2174:1-2193:3" style="letter-spacing: normal;text-align: start;font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;margin-bottom: 16px;overflow-wrap: normal;overflow: auto;line-height: 1.45;border-radius: 4px;border-width: thin;border-style: solid;border-color: rgb(224, 224, 224);caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);"> <section style="display: block;overflow-x: auto;padding: 16px;color: rgb(47, 51, 55);background-color: rgb(246, 246, 246);font-family: Menlo, ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Courier, "Courier New", Monaco, monospace, system-ui, ui-serif, ui-rounded;font-size: 13.6px;word-break: normal;border-radius: 3px;overflow-wrap: normal;line-height: 1.75em;"> <span style="font-size: 15px;">{<br> <span style="color: rgb(1, 86, 146);">"size"</span>: <span style="color: rgb(183, 85, 1);">0</span>,<br> <span style="color: rgb(1, 86, 146);">"aggs"</span>: {<br> <span style="color: rgb(1, 86, 146);">"age_groups"</span>: {<br> <span style="color: rgb(1, 86, 146);">"terms"</span>: {<br> <span style="color: rgb(1, 86, 146);">"field"</span>: <span style="color: rgb(84, 121, 13);">"age_group"</span>,<br> <span style="color: rgb(1, 86, 146);">"size"</span>: <span style="color: rgb(183, 85, 1);">10</span><br> },<br> <span style="color: rgb(1, 86, 146);">"aggs"</span>: {<br> <span style="color: rgb(1, 86, 146);">"total_sales"</span>: {<br> <span style="color: rgb(1, 86, 146);">"sum"</span>: {<br> <span style="color: rgb(1, 86, 146);">"field"</span>: <span style="color: rgb(84, 121, 13);">"price"</span><br> }<br> }<br> }<br> }<br> }<br>}<br></span> </section></pre> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">这个查询语句通过对 </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">age_group</span></code> <span style="font-size: 15px;"> 字段进行 </span> <code style="font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;font-size: 13.6px;padding: 0.14em 0.3em;vertical-align: 5%;background-color: rgba(27, 31, 35, 0.05);border-radius: 3px;border-width: 1px;border-style: solid;border-color: rgb(223, 226, 229);"><span style="font-size: 15px;">terms</span></code> <span style="font-size: 15px;"> 聚合(也就是按照不同的年龄分组值进行分组统计),然后在每个分组内对商品价格进行求和聚合,来获取不同年龄区间的销售总额。</span> </section> <h4 data-sourcepos="2201:1-2201:23" style="margin: 10px auto -1px;padding-left: 3px;font-weight: bold;font-size: 18px;letter-spacing: 0.578px;white-space: normal;border-left-width: 10px;border-left-style: solid;border-left-color: rgb(222, 235, 255);"><span style="margin-top: -1px;padding-top: 6px;padding-right: 5px;padding-left: 5px;font-size: 16px;display: inline-block;line-height: 1.1;">优化效果对比</span></h4> <ul data-sourcepos="2205:1-2211:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;"><strong>性能提升</strong>: 在未进行预索引数据查询优化之前,对于千万级别的订单数据进行年龄范围聚合查询,平均响应时间可能在 5 - 10 秒左右,随着数据量继续增加,响应时间还会进一步拉长。而经过优化后,同样的数据量下,查询响应时间可以缩短到 1 - 2 秒以内,大大提高了业务人员获取数据进行分析的效率。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;"><strong>资源利用优化</strong>: 从 ElasticSearch 集群的资源角度来看,未优化时,复杂的范围聚合查询需要占用较多的 CPU 资源来进行实时的年龄区间划分和数据计算。优化后,由于是基于预聚合的字段进行简单的分组统计,对 CPU 的消耗大幅降低,同时也减少了内存中临时数据的占用,使得集群整体可以更高效地处理更多的查询请求,提升了集群的资源利用率。</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">通过这个电商销售数据统计的案例可以清晰地看到,对于业务中频繁出现的特定范围聚合查询需求,采用预索引数据查询优化的方式,提前对相关数据进行处理和聚合,可以显著提升 ElasticSearch 的查询性能,更好地满足业务分析需求。</span> </section> <h2 data-sourcepos="2216:1-2216:33" style="font-weight: bold;font-size: 22px;margin: 10px auto 5px;border-top-width: 1px;border-top-style: solid;border-top-color: rgb(242, 242, 242);background-color: rgb(242, 242, 242);"><span style="margin-top: -1px;padding-top: 14px;padding-bottom: 14px;padding-right: 5px;padding-left: 5px;font-size: 17px;border-top: 4px solid rgb(33, 33, 34);display: inline-block;line-height: 1.5;font-weight: normal;background-color: rgb(30, 30, 30);border-bottom-right-radius: 100px;color: rgb(255, 255, 255);padding-right: 20px;padding-left: 10px;">7 职责分离,全面监控</span></h2> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">当某个单一角色所负责的业务,或某个单一节点无法满足其业务需要的时候,最好的策略就是 解耦和分离, 常见的操作如:</span> </section> <ul data-sourcepos="2220:1-2224:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">功能分离:本质上也利于服务的轻量化, 百度 搜索引擎的内部人员 聊过 ,百度内部就是基于 Elasticsearch 的源码做修改,删除对其业务不需要的代码,对 ES做轻量化处理</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">业务分离:最简单常见的场景,当我在全文检索服务的时候,应避免在服务期间去执行大量的聚合分析。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">读写分离:常见操作,不做过多解释</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">冷热分离:基于索引生命周期管理策略下的性能动态分配策略。</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">另外, 为了更高的性能, 需要进行密切的、全面的指标监控:</span> </section> <ul data-sourcepos="2227:1-2231:0" style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;padding-left: 2em;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";" class="list-paddingleft-1"> <li style="font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">定期监控集群的健康状况和资源使用情况,以便及时做出调整。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">监控线程池的情况,进行在线的扩容</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">根据实际需求调整索引设置,比如分片数、副本数等。</span> </section></li> <li style="margin-top: 0.25em;font-size: 15px;"> <section style="line-height: 1.75em;"> <span style="font-size: 15px;">考虑使用冷热架构,将活跃数据放在高性能节点上,历史数据则可以迁移到成本更低、性能稍弱的节点上。</span> </section></li> </ul> <section style="font-size: 16px;letter-spacing: normal;text-align: start;white-space: normal;margin-bottom: 16px;caret-color: rgb(36, 41, 46);color: rgb(36, 41, 46);font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";line-height: 1.75em;"> <span style="font-size: 15px;">通过上述措施,可以有效地优化Elasticsearch集群在硬件层面的性能。</span> </section> </section>
作者:微信小助手
<ne-clipboard source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <ne-clipboard source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf=""><br></span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">CPU 飙升是一个常见的问题。</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">在生产环境中,会出现由代码问题导致CPU占用很高,该如何诊断出是哪行java代码导致? 是大家的一项重要基本功,也是大家面试中的家常骗饭。</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">如果连CPU 飙升的问题都回答不清楚, 都支支吾吾, 面试就很难通过了。</span></span></p> <h2 style="font-size: 24px;line-height: 32px;margin: 21px 0 5px 0;text-align: justify;"><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">CPU100%定位的两大神器</span></span></h2> <section style="text-align: center;" nodeleaf=""> <img src="/upload/903f446eba9d0876b7f19b512145ee69.png" class="rich_pages wxw-img" data-ratio="0.33505154639175255" data-s="300,640" data-type="png" data-w="970" type="block" data-imgfileid="100000563"> </section> <h2 style="font-size: 24px;line-height: 32px;margin: 21px 0 5px 0;text-align: justify;"><span leaf=""><span textstyle="" style="font-size: 16px;">想要定位到具体是哪一行的代码导致, 一般都会使用下面的两大神器</span></span></h2> <ul style="margin: 0;padding-left: 23px;" class="list-paddingleft-1"> <li><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">通常使用的jvm自带的工具jstack,</span></span></li> <li><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">还有一种就是开源神器arthas,</span></span></li> </ul> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">一般而言,arthas还有其它的功能,所以选择它多一点.</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf=""><br></span></span></p> <ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u349af361%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%7D%2C%22data%22%3A%22CPU%20%E9%A3%99%E5%8D%87100%25%E7%9A%84%E8%A7%A3%E5%86%B3%E6%80%9D%E8%B7%AF%22%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <p><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">CPU 飙升100%的解决思路</span></span><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">与方法论</span></span></p> <section style="text-align: center;" nodeleaf=""> <img src="/upload/f47c9040269ca45d30d1bc86313bb243.png" class="rich_pages wxw-img" data-ratio="0.3001027749229188" data-s="300,640" data-type="png" data-w="973" type="block" data-imgfileid="100000550"> </section> <p><span leaf=""><br></span></p> <ne-clipboard source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <h2 style="font-size: 24px;line-height: 32px;margin: 21px 0 5px 0;text-align: justify;"><span leaf=""><span textstyle="" style="font-size: 20px;font-weight: bold;">使用jstack 解决CPU 100%问题实操</span></span></h2> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">使用jstack 解决CPU 100%问题,在方法论上要用到两个命令,</span></span></p> <ul style="margin: 0;padding-left: 23px;" class="list-paddingleft-1"> <li><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">top 命令查看TOP N线程,</span></span></li> <li><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">jstack命令查看堆栈信息</span></span></li> </ul> <section style="text-align: center;" nodeleaf=""> <img src="/upload/e5cef8ab4cf8da21d44bd7f99cd2b844.png" class="rich_pages wxw-img" data-ratio="0.19328703703703703" data-s="300,640" data-type="png" data-w="864" type="block" data-imgfileid="100000551"> </section> <ne-clipboard source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <h3 style="font-size: 20;line-height: 28px;margin: 16px 0 5px 0;text-align: justify;"><span style="color: rgb(30, 30, 30);background-color: rgb(212, 224, 250);"><span leaf="">1.jstack命令讲解</span></span></h3> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">命令jstack是java堆栈的跟踪工具,可以打印出程序中所有线程的堆栈信息,包括线程状态,调用栈信息,锁信息等。</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">jstack可以诊断线程死锁、内存泄漏等问题</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">命令格式: jstack [options] pid</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(106, 115, 125);background-color: rgb(249, 249, 249);font-size: 16px;"><span leaf="">常用例子: jstack -l pid,查看线程的堆栈信息</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">堆栈信息解读:</span></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="sql"><code><span leaf=""><span class="code-snippet__plaintext">[root</span><span class="code-snippet__variable">@192</span><span class="code-snippet__number">-168-65-185</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">~</span><span class="code-snippet__plaintext">]# jstack </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext">l </span><span class="code-snippet__number">29440</span></span></code><code><span leaf=""><span class="code-snippet__number">2024-12-17</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">13</span><span class="code-snippet__plaintext">:</span><span class="code-snippet__number">48</span><span class="code-snippet__plaintext">:</span><span class="code-snippet__number">51</span></span></code><code><span leaf=""><span class="code-snippet__keyword">Full</span><span class="code-snippet__plaintext"> thread dump OpenJDK </span><span class="code-snippet__number">64</span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext">Bit Server VM (</span><span class="code-snippet__number">25.412</span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext">b08 mixed mode):</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"Attach Listener" #</span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext"> daemon prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">9</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f097c001000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x763a</span><span class="code-snippet__plaintext"> runnable [</span><span class="code-snippet__number">0x0000000000000000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: RUNNABLE</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">None</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"DestroyJavaVM" #</span><span class="code-snippet__number">11</span><span class="code-snippet__plaintext"> prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">5</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e004b800</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7301</span><span class="code-snippet__plaintext"> waiting </span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">condition</span><span class="code-snippet__plaintext"> [</span><span class="code-snippet__number">0x0000000000000000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: RUNNABLE</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">None</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"pool-1-thread-1" #</span><span class="code-snippet__number">10</span><span class="code-snippet__plaintext"> prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">5</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e0166000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7316</span><span class="code-snippet__plaintext"> runnable [</span><span class="code-snippet__number">0x00007f09cc9cb000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: RUNNABLE</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> com.tuling.learnjuc.demo.JVMCPU$CPUTask.run(JVMCPU.java:</span><span class="code-snippet__number">16</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> locked </span><span class="code-snippet__operator"><</span><span class="code-snippet__number">0x0000000757d645b8</span><span class="code-snippet__operator">></span><span class="code-snippet__plaintext"> (a java.lang.Object)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:</span><span class="code-snippet__number">1149</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:</span><span class="code-snippet__number">624</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.lang.Thread.run(Thread.java:</span><span class="code-snippet__number">750</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator"><</span><span class="code-snippet__number">0x0000000757d65d00</span><span class="code-snippet__operator">></span><span class="code-snippet__plaintext"> (a java.util.concurrent.ThreadPoolExecutor$Worker)</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"Service Thread" #</span><span class="code-snippet__number">9</span><span class="code-snippet__plaintext"> daemon prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">9</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e0140000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7314</span><span class="code-snippet__plaintext"> runnable [</span><span class="code-snippet__number">0x0000000000000000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: RUNNABLE</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">None</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"C1 CompilerThread3" #</span><span class="code-snippet__number">8</span><span class="code-snippet__plaintext"> daemon prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">9</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e0133000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7313</span><span class="code-snippet__plaintext"> waiting </span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">condition</span><span class="code-snippet__plaintext"> [</span><span class="code-snippet__number">0x0000000000000000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: RUNNABLE</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">None</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"C2 CompilerThread2" #</span><span class="code-snippet__number">7</span><span class="code-snippet__plaintext"> daemon prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">9</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e0131000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7312</span><span class="code-snippet__plaintext"> waiting </span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">condition</span><span class="code-snippet__plaintext"> [</span><span class="code-snippet__number">0x0000000000000000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: RUNNABLE</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">None</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"C2 CompilerThread1" #</span><span class="code-snippet__number">6</span><span class="code-snippet__plaintext"> daemon prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">9</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e012f000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7311</span><span class="code-snippet__plaintext"> waiting </span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">condition</span><span class="code-snippet__plaintext"> [</span><span class="code-snippet__number">0x0000000000000000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: RUNNABLE</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">None</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"C2 CompilerThread0" #</span><span class="code-snippet__number">5</span><span class="code-snippet__plaintext"> daemon prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">9</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e012c800</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7310</span><span class="code-snippet__plaintext"> waiting </span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">condition</span><span class="code-snippet__plaintext"> [</span><span class="code-snippet__number">0x0000000000000000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: RUNNABLE</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">None</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"Signal Dispatcher" #</span><span class="code-snippet__number">4</span><span class="code-snippet__plaintext"> daemon prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">9</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e011e000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x730f</span><span class="code-snippet__plaintext"> runnable [</span><span class="code-snippet__number">0x0000000000000000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: RUNNABLE</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">None</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"Finalizer" #</span><span class="code-snippet__number">3</span><span class="code-snippet__plaintext"> daemon prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">8</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e00f2000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x730e</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">in</span><span class="code-snippet__plaintext"> Object.wait() [</span><span class="code-snippet__number">0x00007f09cd1d3000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: WAITING (</span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> object monitor)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.lang.Object.wait(Native </span><span class="code-snippet__keyword">Method</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> waiting </span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator"><</span><span class="code-snippet__number">0x0000000757d08f00</span><span class="code-snippet__operator">></span><span class="code-snippet__plaintext"> (a java.lang.ref.ReferenceQueue$Lock)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:</span><span class="code-snippet__number">144</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> locked </span><span class="code-snippet__operator"><</span><span class="code-snippet__number">0x0000000757d08f00</span><span class="code-snippet__operator">></span><span class="code-snippet__plaintext"> (a java.lang.ref.ReferenceQueue$Lock)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:</span><span class="code-snippet__number">165</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:</span><span class="code-snippet__number">188</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">None</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"Reference Handler" #</span><span class="code-snippet__number">2</span><span class="code-snippet__plaintext"> daemon prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">10</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e00ed000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x730d</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">in</span><span class="code-snippet__plaintext"> Object.wait() [</span><span class="code-snippet__number">0x00007f09cd2d4000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: WAITING (</span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> object monitor)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.lang.Object.wait(Native </span><span class="code-snippet__keyword">Method</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> waiting </span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator"><</span><span class="code-snippet__number">0x0000000757d06b98</span><span class="code-snippet__operator">></span><span class="code-snippet__plaintext"> (a java.lang.ref.Reference$Lock)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.lang.Object.wait(Object.java:</span><span class="code-snippet__number">502</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.lang.ref.Reference.tryHandlePending(Reference.java:</span><span class="code-snippet__number">191</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> locked </span><span class="code-snippet__operator"><</span><span class="code-snippet__number">0x0000000757d06b98</span><span class="code-snippet__operator">></span><span class="code-snippet__plaintext"> (a java.lang.ref.Reference$Lock)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.lang.ref.Reference$ReferenceHandler.run(Reference.java:</span><span class="code-snippet__number">153</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">None</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"VM Thread" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e00e3800</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x730c</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"GC task thread#0 (ParallelGC)" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e005e000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7302</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"GC task thread#1 (ParallelGC)" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e0060000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7303</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"GC task thread#2 (ParallelGC)" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e0062000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7304</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"GC task thread#3 (ParallelGC)" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e0064000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7305</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"GC task thread#4 (ParallelGC)" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e0065800</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7306</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"GC task thread#5 (ParallelGC)" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e0067800</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7307</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"GC task thread#6 (ParallelGC)" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e0069800</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7308</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"GC task thread#7 (ParallelGC)" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e006b800</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7309</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"GC task thread#8 (ParallelGC)" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e006d000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x730a</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"GC task thread#9 (ParallelGC)" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e006f000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x730b</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"VM Periodic Task Thread" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e0142800</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7315</span><span class="code-snippet__plaintext"> waiting </span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">condition</span><span class="code-snippet__plaintext"> </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">JNI </span><span class="code-snippet__keyword">global</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">references</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">5</span></span></code><code><span leaf=""><br></span></code></pre> </section> <ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%22uf892165a%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22ua64d9cd3%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E4%BD%A0%E4%BC%9A%E5%8F%91%E7%8E%B0%E4%B8%8A%E9%9D%A2%E7%9A%84%E4%BF%A1%E6%81%AF%E5%85%B6%E5%AE%9E%E6%98%AF%E4%B8%80%E6%AE%B5%E4%B8%80%E6%AE%B5%E7%9A%84%EF%BC%8C%E6%91%98%E5%8F%96%E5%85%B6%E4%B8%AD%E7%9A%84%E4%B8%80%E6%AE%B5%E4%B8%BA%E5%A4%A7%E5%AE%B6%E8%AF%B4%E6%98%8E%3A%22%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">你会发现上面的信息其实是一段一段的,摘取其中的一段为大家说明:</span></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="swift"><code><span leaf=""><span class="code-snippet__string">"pool-1-thread-1"</span><span class="code-snippet__plaintext"> #</span><span class="code-snippet__number">10</span><span class="code-snippet__plaintext"> prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">5</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007f09e0166000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7316</span><span class="code-snippet__plaintext"> runnable [</span><span class="code-snippet__number">0x00007f09cc9cb000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.</span><span class="code-snippet__type">Thread</span><span class="code-snippet__plaintext">.</span><span class="code-snippet__type">State</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__type">RUNNABLE</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> at com.tuling.learnjuc.demo.</span><span class="code-snippet__type">JVMCPU</span><span class="code-snippet__variable">$CPUTask</span><span class="code-snippet__plaintext">.run(</span><span class="code-snippet__type">JVMCPU</span><span class="code-snippet__plaintext">.java:</span><span class="code-snippet__number">16</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> locked </span><span class="code-snippet__operator"><</span><span class="code-snippet__number">0x0000000757d645b8</span><span class="code-snippet__operator">></span><span class="code-snippet__plaintext"> (a java.lang.</span><span class="code-snippet__type">Object</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> at java.util.concurrent.</span><span class="code-snippet__type">ThreadPoolExecutor</span><span class="code-snippet__plaintext">.runWorker(</span><span class="code-snippet__type">ThreadPoolExecutor</span><span class="code-snippet__plaintext">.java:</span><span class="code-snippet__number">1149</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> at java.util.concurrent.</span><span class="code-snippet__type">ThreadPoolExecutor</span><span class="code-snippet__variable">$Worker</span><span class="code-snippet__plaintext">.run(</span><span class="code-snippet__type">ThreadPoolExecutor</span><span class="code-snippet__plaintext">.java:</span><span class="code-snippet__number">624</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> at java.lang.</span><span class="code-snippet__type">Thread</span><span class="code-snippet__plaintext">.run(</span><span class="code-snippet__type">Thread</span><span class="code-snippet__plaintext">.java:</span><span class="code-snippet__number">750</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__type">Locked</span><span class="code-snippet__plaintext"> ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator"><</span><span class="code-snippet__number">0x0000000757d65d00</span><span class="code-snippet__operator">></span><span class="code-snippet__plaintext"> (a java.util.concurrent.</span><span class="code-snippet__type">ThreadPoolExecutor</span><span class="code-snippet__variable">$Worker</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><br></span></code></pre> </section> <ne-clipboard source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">pool-1-thread-1</span></span></code><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">:线程名称</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">#1</span></span></code><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">:当前线程ID,从main开始,jvm会根据线程创建的顺序为其线程编号</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">prio</span></span></code><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">:优先级的顺序,一般默认是5</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">os_prio</span></span></code><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">:线程对应系统的优先级</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">tid</span></span></code><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">:java内的线程id</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">nid</span></span></code><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">:操作系统级别的线程id,是一个十六进制</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">关于线程的信息:</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">NEW</span></span></code><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">:线程新建,还没开始运行</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">RUNNABLE</span></span></code><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">:正在java虚拟机中运行的线程</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">BLOCKED</span></span></code><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">:被阻塞,正在等待监视器锁的线程</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">WAITING</span></span></code><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">:无限期等待另一个线程执行特定操作的线程</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">TIMED_WAITING</span></span></code><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">:等待另一个线程执行操作达到指定等待时间的线程</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">TERMINATED</span></span></code><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">:已经退出的线程</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">我们这里关注的最多的就是</span></span><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">nid</span></span></code></p> <p><span leaf=""><br></span></p> <ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%22cac793bb%22%2C%22name%22%3A%22h3%22%2C%22attrs%22%3A%7B%22alignment%22%3A%22justify%22%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22uc66edf16%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(30%2C%2030%2C%2030)%22%2C%22bgColor%22%3A%22rgb(212%2C%20224%2C%20250)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%222.%E4%BD%BF%E7%94%A8jstack%E8%A7%A3%E5%86%B3CPU%E5%8D%A0%E7%94%A8%E5%BE%88%E9%AB%98%E7%9A%84%E9%97%AE%E9%A2%98%E5%B9%B6%E5%AE%9A%E4%BD%8D%E5%85%B7%E4%BD%93%E8%A1%8C%E6%95%B0%22%7D%5D%7D%2C%7B%22type%22%3A%22element%22%2C%22id%22%3A%22u60a188f0%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22ue7737189%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E5%85%88%E6%9D%A5%E7%9C%8B%E4%B8%80%E6%AE%B5%E4%BB%A3%E7%A0%81%3A%22%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <h3 style="font-size: 20;line-height: 28px;margin: 16px 0 5px 0;text-align: justify;"><span style="color: rgb(30, 30, 30);background-color: rgb(212, 224, 250);"><span leaf="">2.使用jstack解决CPU占用很高的问题并定位具体行数</span></span></h3> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">先来看一段代码:</span></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="java"><code><span leaf=""><span class="code-snippet__keyword">package</span><span class="code-snippet__plaintext"> com.tuling.learnjuc.demo;</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__keyword">import</span><span class="code-snippet__plaintext"> java.util.concurrent.ExecutorService;</span></span></code><code><span leaf=""><span class="code-snippet__keyword">import</span><span class="code-snippet__plaintext"> java.util.concurrent.Executors;</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__keyword">public</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">class</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__title">JVMCPU</span><span class="code-snippet__plaintext"> {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">private</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">static</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__type">ExecutorService</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__variable">service</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">=</span><span class="code-snippet__plaintext"> Executors.newFixedThreadPool(</span><span class="code-snippet__number">5</span><span class="code-snippet__plaintext">);</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">private</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">static</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__type">Object</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__variable">lock</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">=</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">new</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__title">Object</span><span class="code-snippet__plaintext">();</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">public</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">static</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">class</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__title">CPUTask</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">implements</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__title">Runnable</span><span class="code-snippet__plaintext">{</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__meta">@Override</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">public</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">void</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__title">run</span><span class="code-snippet__params">()</span><span class="code-snippet__plaintext"> {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">synchronized</span><span class="code-snippet__plaintext"> (lock){</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__type">long</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__variable">sum</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">=</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">0L</span><span class="code-snippet__plaintext">;</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">while</span><span class="code-snippet__plaintext">(</span><span class="code-snippet__literal">true</span><span class="code-snippet__plaintext">){</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> sum +=</span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext">;</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> }</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> }</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> }</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> }</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">public</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">static</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">void</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__title">main</span><span class="code-snippet__params">(String[] args)</span><span class="code-snippet__plaintext"> {</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__type">CPUTask</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__variable">cpuTask</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">=</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">new</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__title">CPUTask</span><span class="code-snippet__plaintext">();</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> service.execute(cpuTask);</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> }</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">}</span></span></code></pre> </section> <ne-clipboard source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">将这段代码上传到linux服务器上编译</span></span></p> <blockquote> <p><span leaf="">注意:如果提示javac: 未找到命令... ,执行yum install java-1.8.0-openjdk-devel</span></p> </blockquote> <section style="text-align: center;" nodeleaf=""> <img src="/upload/6308f670d43b04544082eea73df6eb9d.png" class="rich_pages wxw-img" data-ratio="0.15648148148148147" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="100000552"> </section> <ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%22ua6fa8133%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22uc6d06727%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E4%BD%BF%E7%94%A8%22%7D%2C%7B%22type%22%3A%22element%22%2C%22id%22%3A%22ub2fca604%22%2C%22name%22%3A%22code%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22ub57edd22%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A14%7D%2C%22data%22%3A%22nohup%20java%20com.tuling.learnjuc.demo.JVMCPU%20%26%22%7D%5D%7D%2C%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u4b0806c9%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E8%BF%90%E8%A1%8C%22%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">使用</span></span><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">nohup java com.tuling.learnjuc.demo.JVMCPU &</span></span></code><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">运行</span></span></p> <section style="text-align: center;" nodeleaf=""> <img src="/upload/a12b669534709ff59d3119cb89b5d9ba.png" class="rich_pages wxw-img" data-ratio="0.09259259259259259" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="100000553"> </section> <ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%22u3956adf8%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22uc0f107ee%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E4%BD%BF%E7%94%A8%22%7D%2C%7B%22type%22%3A%22element%22%2C%22id%22%3A%22u2e993f78%22%2C%22name%22%3A%22code%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u9aa59a80%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A14%7D%2C%22data%22%3A%22top%22%7D%5D%7D%2C%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u7a5b5797%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E5%91%BD%E4%BB%A4%E5%8F%AF%E4%BB%A5%E7%9C%8B%E5%88%B0cpu%E8%A2%AB%E6%89%93%E6%BB%A1%E4%BA%86%22%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">使用</span></span><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">top</span></span></code><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">命令可以看到cpu被打满了</span></span></p> <section style="text-align: center;" nodeleaf=""> <img src="/upload/705102066230ac8b4e6da507a87ba670.png" class="rich_pages wxw-img" data-ratio="0.2518518518518518" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="100000554"> </section> <ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%22u02192818%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u6217cd25%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E7%9F%A5%E9%81%93%E4%BA%86%E8%BF%9B%E7%A8%8B%E7%9A%84PID%EF%BC%8C%E5%A6%82%E4%BD%95%E6%89%BE%E5%88%B0%E8%BF%9B%E7%A8%8B%E4%B8%8B%E6%98%AF%E5%93%AA%E4%B8%AA%E7%BA%BF%E7%A8%8B%E5%91%A2%3F%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8%E5%91%BD%E4%BB%A4%22%7D%2C%7B%22type%22%3A%22element%22%2C%22id%22%3A%22u6e9b242b%22%2C%22name%22%3A%22code%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u4d9d0f9e%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A14%7D%2C%22data%22%3A%22top%20-Hp%2032208%22%7D%5D%7D%2C%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u733b01bb%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%EF%BC%8C%E5%A6%82%E4%B8%8B%E6%89%80%E7%A4%BA%22%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">知道了进程的PID,如何找到进程下是哪个线程呢?可以使用命令</span></span><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">top -Hp 32208</span></span></code><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">,如下所示</span></span></p> <section style="text-align: center;" nodeleaf=""> <img src="/upload/aad572d136738c1c52b22e0712e02574.png" class="rich_pages wxw-img" data-ratio="0.41759259259259257" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="100000555"> </section> <ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%22ua9754ccd%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u756781cf%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E5%A6%82%E6%9E%9C%E8%83%BD%E8%8E%B7%E5%8F%96%E5%88%B0%E7%BA%BF%E7%A8%8B%E5%90%8D%EF%BC%8C%E4%B8%8B%E9%9D%A2%E8%BF%99%E6%AD%A5%E5%8F%AF%E4%BB%A5%E5%BF%BD%E7%95%A5%22%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">如果能获取到线程名,下面这步可以忽略,不需要根据线程id找线程</span></span></p> <ne-clipboard source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <blockquote> <p><span leaf="">从上面的图可以看到,cpu占用最多的线程是32230这个线程id,接下来就是使用jstack命令来查看程序的所有堆栈信息,但是,这里需要有一个注意的点,32230这个是一个十进制的,使用jstack看到的nid是十六进制,所以我们需要转换,可以使用printf "%x\n"这个命令</span></p> </blockquote> <section style="text-align: center;" nodeleaf=""> <img src="/upload/82d59d77bd9a585d0d33e504c255ba3f.png" class="rich_pages wxw-img" data-ratio="0.09235352532274081" data-s="300,640" data-type="png" data-w="1007" type="block" data-imgfileid="100000556"> </section> <ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%22uc00ab2f9%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u1c78913f%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E6%8E%A5%E4%B8%8B%E6%9D%A5%E4%BD%BF%E7%94%A8%22%7D%2C%7B%22type%22%3A%22element%22%2C%22id%22%3A%22u30ca27f7%22%2C%22name%22%3A%22code%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u57e962c7%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A14%7D%2C%22data%22%3A%22jstack%20-l%2032208%22%7D%5D%7D%2C%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u057484d9%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E6%89%93%E5%8D%B0%E5%A0%86%E6%A0%88%E4%BF%A1%E6%81%AF%22%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">接下来使用</span></span><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">jstack -l 32208</span></span></code><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">打印堆栈信息</span></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="sql"><code><span leaf=""><span class="code-snippet__plaintext">[root</span><span class="code-snippet__variable">@192</span><span class="code-snippet__number">-168-65-185</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">~</span><span class="code-snippet__plaintext">]# jstack </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext">l </span><span class="code-snippet__number">32208</span></span></code><code><span leaf=""><span class="code-snippet__number">2024-12-17</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">14</span><span class="code-snippet__plaintext">:</span><span class="code-snippet__number">04</span><span class="code-snippet__plaintext">:</span><span class="code-snippet__number">09</span></span></code><code><span leaf=""><span class="code-snippet__keyword">Full</span><span class="code-snippet__plaintext"> thread dump OpenJDK </span><span class="code-snippet__number">64</span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext">Bit Server VM (</span><span class="code-snippet__number">25.412</span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext">b08 mixed mode):</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"Attach Listener" #</span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext"> daemon prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">9</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb498001000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x4e5</span><span class="code-snippet__plaintext"> waiting </span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">condition</span><span class="code-snippet__plaintext"> [</span><span class="code-snippet__number">0x0000000000000000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: RUNNABLE</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">None</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"DestroyJavaVM" #</span><span class="code-snippet__number">11</span><span class="code-snippet__plaintext"> prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">5</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc04b800</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7dd1</span><span class="code-snippet__plaintext"> waiting </span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">condition</span><span class="code-snippet__plaintext"> [</span><span class="code-snippet__number">0x0000000000000000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: RUNNABLE</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">None</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"pool-1-thread-1" #</span><span class="code-snippet__number">10</span><span class="code-snippet__plaintext"> prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">5</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc16e000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7de6</span><span class="code-snippet__plaintext"> runnable [</span><span class="code-snippet__number">0x00007fb4e87fe000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: RUNNABLE</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> com.tuling.learnjuc.demo.JVMCPU$CPUTask.run(JVMCPU.java:</span><span class="code-snippet__number">16</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> locked </span><span class="code-snippet__operator"><</span><span class="code-snippet__number">0x0000000757d645b8</span><span class="code-snippet__operator">></span><span class="code-snippet__plaintext"> (a java.lang.Object)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:</span><span class="code-snippet__number">1149</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:</span><span class="code-snippet__number">624</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.lang.Thread.run(Thread.java:</span><span class="code-snippet__number">750</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator"><</span><span class="code-snippet__number">0x0000000757d65d00</span><span class="code-snippet__operator">></span><span class="code-snippet__plaintext"> (a java.util.concurrent.ThreadPoolExecutor$Worker)</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"Service Thread" #</span><span class="code-snippet__number">9</span><span class="code-snippet__plaintext"> daemon prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">9</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc140000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7de4</span><span class="code-snippet__plaintext"> runnable [</span><span class="code-snippet__number">0x0000000000000000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: RUNNABLE</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">None</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"C1 CompilerThread3" #</span><span class="code-snippet__number">8</span><span class="code-snippet__plaintext"> daemon prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">9</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc133000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7de3</span><span class="code-snippet__plaintext"> waiting </span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">condition</span><span class="code-snippet__plaintext"> [</span><span class="code-snippet__number">0x0000000000000000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: RUNNABLE</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">None</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"C2 CompilerThread2" #</span><span class="code-snippet__number">7</span><span class="code-snippet__plaintext"> daemon prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">9</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc131000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7de2</span><span class="code-snippet__plaintext"> waiting </span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">condition</span><span class="code-snippet__plaintext"> [</span><span class="code-snippet__number">0x0000000000000000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: RUNNABLE</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">None</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"C2 CompilerThread1" #</span><span class="code-snippet__number">6</span><span class="code-snippet__plaintext"> daemon prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">9</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc12f000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7de1</span><span class="code-snippet__plaintext"> waiting </span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">condition</span><span class="code-snippet__plaintext"> [</span><span class="code-snippet__number">0x0000000000000000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: RUNNABLE</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">None</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"C2 CompilerThread0" #</span><span class="code-snippet__number">5</span><span class="code-snippet__plaintext"> daemon prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">9</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc12c800</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7de0</span><span class="code-snippet__plaintext"> waiting </span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">condition</span><span class="code-snippet__plaintext"> [</span><span class="code-snippet__number">0x0000000000000000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: RUNNABLE</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">None</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"Signal Dispatcher" #</span><span class="code-snippet__number">4</span><span class="code-snippet__plaintext"> daemon prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">9</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc11e000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7ddf</span><span class="code-snippet__plaintext"> runnable [</span><span class="code-snippet__number">0x0000000000000000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: RUNNABLE</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">None</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"Finalizer" #</span><span class="code-snippet__number">3</span><span class="code-snippet__plaintext"> daemon prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">8</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc0f2000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7dde</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">in</span><span class="code-snippet__plaintext"> Object.wait() [</span><span class="code-snippet__number">0x00007fb4e92d4000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: WAITING (</span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> object monitor)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.lang.Object.wait(Native </span><span class="code-snippet__keyword">Method</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> waiting </span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator"><</span><span class="code-snippet__number">0x0000000757d08f00</span><span class="code-snippet__operator">></span><span class="code-snippet__plaintext"> (a java.lang.ref.ReferenceQueue$Lock)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:</span><span class="code-snippet__number">144</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> locked </span><span class="code-snippet__operator"><</span><span class="code-snippet__number">0x0000000757d08f00</span><span class="code-snippet__operator">></span><span class="code-snippet__plaintext"> (a java.lang.ref.ReferenceQueue$Lock)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:</span><span class="code-snippet__number">165</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:</span><span class="code-snippet__number">188</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">None</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"Reference Handler" #</span><span class="code-snippet__number">2</span><span class="code-snippet__plaintext"> daemon prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">10</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc0ed000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7ddd</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">in</span><span class="code-snippet__plaintext"> Object.wait() [</span><span class="code-snippet__number">0x00007fb4e93d5000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.Thread.State: WAITING (</span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> object monitor)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.lang.Object.wait(Native </span><span class="code-snippet__keyword">Method</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> waiting </span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator"><</span><span class="code-snippet__number">0x0000000757d06b98</span><span class="code-snippet__operator">></span><span class="code-snippet__plaintext"> (a java.lang.ref.Reference$Lock)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.lang.Object.wait(Object.java:</span><span class="code-snippet__number">502</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.lang.ref.Reference.tryHandlePending(Reference.java:</span><span class="code-snippet__number">191</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> locked </span><span class="code-snippet__operator"><</span><span class="code-snippet__number">0x0000000757d06b98</span><span class="code-snippet__operator">></span><span class="code-snippet__plaintext"> (a java.lang.ref.Reference$Lock)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">at</span><span class="code-snippet__plaintext"> java.lang.ref.Reference$ReferenceHandler.run(Reference.java:</span><span class="code-snippet__number">153</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> Locked ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">None</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"VM Thread" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc0e3800</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7ddc</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"GC task thread#0 (ParallelGC)" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc05e000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7dd2</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"GC task thread#1 (ParallelGC)" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc060000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7dd3</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"GC task thread#2 (ParallelGC)" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc062000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7dd4</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"GC task thread#3 (ParallelGC)" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc064000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7dd5</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"GC task thread#4 (ParallelGC)" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc065800</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7dd6</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"GC task thread#5 (ParallelGC)" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc067800</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7dd7</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"GC task thread#6 (ParallelGC)" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc069800</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7dd8</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"GC task thread#7 (ParallelGC)" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc06b800</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7dd9</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"GC task thread#8 (ParallelGC)" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc06d000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7dda</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"GC task thread#9 (ParallelGC)" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc06f000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7ddb</span><span class="code-snippet__plaintext"> runnable </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">"VM Periodic Task Thread" os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc142800</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7de5</span><span class="code-snippet__plaintext"> waiting </span><span class="code-snippet__keyword">on</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">condition</span><span class="code-snippet__plaintext"> </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">JNI </span><span class="code-snippet__keyword">global</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">references</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">5</span></span></code></pre> </section> <ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%22u945352f9%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22ua36776a6%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E4%BB%8E%E4%B8%8A%E9%9D%A2%E7%9A%84%E4%BF%A1%E6%81%AF%E4%B8%AD%EF%BC%8C%E5%8F%AF%E4%BB%A5%E7%9C%8B%E5%88%B0%E8%BD%AC%E6%8D%A2%E7%9A%84%E7%BB%93%E6%9E%9C%E5%92%8Cnid%E6%98%AF%E4%B8%80%E8%87%B4%E7%9A%84%EF%BC%8C%22%7D%5D%7D%2C%7B%22type%22%3A%22element%22%2C%22id%22%3A%22u785f5c7c%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22uf33a65a8%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E4%BB%8E%E4%B8%8B%E9%9D%A2%E7%9A%84%E4%BF%A1%E6%81%AF%E4%B8%AD%E5%B0%B1%E5%8F%AF%E4%BB%A5%E7%9C%8B%E5%88%B0%E9%97%AE%E9%A2%98%E5%85%B6%E5%AE%9E%E6%98%AF%E5%87%BA%E7%8E%B0%E5%9C%A8%22%7D%2C%7B%22type%22%3A%22element%22%2C%22id%22%3A%22ue3e43fb0%22%2C%22name%22%3A%22code%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u5a80d1f9%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A14%7D%2C%22data%22%3A%22JVMCPU.java%22%7D%5D%7D%2C%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u890b199a%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E7%9A%8416%E8%A1%8C%E5%B7%A6%E5%8F%B3%EF%BC%8C%E8%BF%99%E9%87%8C%E7%BB%99%E5%87%BA%E7%9A%84%E6%98%AF16%E8%A1%8C%EF%BC%8C%E4%BD%86%E6%98%AF%E5%AE%9E%E9%99%85%E6%83%85%E5%86%B5%E6%98%AF16%E8%A1%8C%E7%9A%84%E9%99%84%E8%BF%91%22%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">从上面的信息中,可以看到转换的结果和nid是一致的,</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">从下面的信息中就可以看到问题其实是出现在</span></span><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">JVMCPU.java</span></span></code><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">的16行左右,这里给出的是16行,但是实际情况是16行的附近</span></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="swift"><code><span leaf=""><span class="code-snippet__string">"pool-1-thread-1"</span><span class="code-snippet__plaintext"> #</span><span class="code-snippet__number">10</span><span class="code-snippet__plaintext"> prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">5</span><span class="code-snippet__plaintext"> os_prio</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> tid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x00007fb4fc16e000</span><span class="code-snippet__plaintext"> nid</span><span class="code-snippet__operator">=</span><span class="code-snippet__number">0x7de6</span><span class="code-snippet__plaintext"> runnable [</span><span class="code-snippet__number">0x00007fb4e87fe000</span><span class="code-snippet__plaintext">]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> java.lang.</span><span class="code-snippet__type">Thread</span><span class="code-snippet__plaintext">.</span><span class="code-snippet__type">State</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__type">RUNNABLE</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> at com.tuling.learnjuc.demo.</span><span class="code-snippet__type">JVMCPU</span><span class="code-snippet__variable">$CPUTask</span><span class="code-snippet__plaintext">.run(</span><span class="code-snippet__type">JVMCPU</span><span class="code-snippet__plaintext">.java:</span><span class="code-snippet__number">16</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> locked </span><span class="code-snippet__operator"><</span><span class="code-snippet__number">0x0000000757d645b8</span><span class="code-snippet__operator">></span><span class="code-snippet__plaintext"> (a java.lang.</span><span class="code-snippet__type">Object</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> at java.util.concurrent.</span><span class="code-snippet__type">ThreadPoolExecutor</span><span class="code-snippet__plaintext">.runWorker(</span><span class="code-snippet__type">ThreadPoolExecutor</span><span class="code-snippet__plaintext">.java:</span><span class="code-snippet__number">1149</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> at java.util.concurrent.</span><span class="code-snippet__type">ThreadPoolExecutor</span><span class="code-snippet__variable">$Worker</span><span class="code-snippet__plaintext">.run(</span><span class="code-snippet__type">ThreadPoolExecutor</span><span class="code-snippet__plaintext">.java:</span><span class="code-snippet__number">624</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> at java.lang.</span><span class="code-snippet__type">Thread</span><span class="code-snippet__plaintext">.run(</span><span class="code-snippet__type">Thread</span><span class="code-snippet__plaintext">.java:</span><span class="code-snippet__number">750</span><span class="code-snippet__plaintext">)</span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__type">Locked</span><span class="code-snippet__plaintext"> ownable synchronizers:</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator"><</span><span class="code-snippet__number">0x0000000757d65d00</span><span class="code-snippet__operator">></span><span class="code-snippet__plaintext"> (a java.util.concurrent.</span><span class="code-snippet__type">ThreadPoolExecutor</span><span class="code-snippet__variable">$Worker</span><span class="code-snippet__plaintext">)</span></span></code></pre> </section> <ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%22u735539b8%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u1cf8c957%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E7%BB%93%E5%90%88%E4%BB%A3%E7%A0%81%E6%9D%A5%E7%9C%8B%E4%B8%80%E4%B8%8B%E5%B0%B1%E5%BE%88%E5%AE%B9%E6%98%93%E9%97%AE%E9%A2%98%22%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">结合代码来看一下就很容易问题</span></span></p> <section style="text-align: center;" nodeleaf=""> <img src="/upload/bb317db1e974d25ffad82477018eef05.png" class="rich_pages wxw-img" data-ratio="0.5370370370370371" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="100000557"> </section> <ne-clipboard source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <h2 style="font-size: 24px;line-height: 32px;margin: 21px 0 5px 0;text-align: justify;"><span leaf="">使用arthas解决CPU占用很高的问题,定位具体代码行</span></h2> <blockquote> <p><span leaf="">官方文档:https://arthas.aliyun.com/</span></p> </blockquote> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">使用arthas解决CPU 100%问题,在方法论上要用到两个命令,</span></span></p> <ul style="margin: 0;padding-left: 23px;" class="list-paddingleft-1"> <li><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">dashboard 命令查看TOP N线程,</span></span></li> <li><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">thread 命令查看堆栈信息</span></span></li> </ul> <section style="text-align: center;" nodeleaf=""> <img src="/upload/3d18c01c27599aee3b71ff26de99cd51.png" class="rich_pages wxw-img" data-ratio="0.1875" data-s="300,640" data-type="png" data-w="960" type="block" data-imgfileid="100000558"> </section> <ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%22ued510460%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22ufc299fb5%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E5%85%88%E6%9D%A5%E8%BF%90%E8%A1%8C%22%7D%2C%7B%22type%22%3A%22element%22%2C%22id%22%3A%22uea1befb8%22%2C%22name%22%3A%22code%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22uf9070dcd%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A14%7D%2C%22data%22%3A%22arthas%22%7D%5D%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">先来运行</span></span><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">arthas</span></span></code></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="javascript"><code><span leaf=""><span class="code-snippet__plaintext">curl -O </span><span class="code-snippet__attr">https</span><span class="code-snippet__plaintext">:</span><span class="code-snippet__comment">//arthas.aliyun.com/arthas-boot.jar</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">java -jar arthas-boot.jar</span></span></code></pre> </section> <section style="text-align: center;" nodeleaf=""> <img src="/upload/e36a50ada6d50c481516880aa0f53d49.png" class="rich_pages wxw-img" data-ratio="0.15648148148148147" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="100000559"> </section> <ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%22u9ce49312%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u7fe07ffd%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E8%BE%93%E5%85%A51%E6%98%BE%E7%A4%BA%E5%A6%82%E4%B8%8B%22%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">输入1显示如下</span></span></p> <section style="text-align: center;" nodeleaf=""> <img src="/upload/88c44b712e6225727d6e40767843f9d1.png" class="rich_pages wxw-img" data-ratio="0.42962962962962964" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="100000560"> </section> <ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%22uf850238f%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u2903f06b%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E8%BE%93%E5%85%A5%22%7D%2C%7B%22type%22%3A%22element%22%2C%22id%22%3A%22u1b8a3032%22%2C%22name%22%3A%22code%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u185ac0da%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A14%7D%2C%22data%22%3A%22dashboard%22%7D%5D%7D%2C%7B%22type%22%3A%22text%22%2C%22id%22%3A%22ub9d55c98%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E5%91%BD%E4%BB%A4%E5%8F%AF%E4%BB%A5%E7%9C%8B%E5%88%B0%E6%98%AF%E5%93%AA%E4%B8%AA%E7%BA%BF%E7%A8%8B%E5%8D%A0%E7%94%A8cpu%E6%9C%80%E9%AB%98%22%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">输入</span></span><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">dashboard</span></span></code><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">命令可以看到是哪个线程占用cpu最高</span></span></p> <section style="text-align: center;" nodeleaf=""> <img src="/upload/677ff822ea056b5a88fdd152c7cf7d0b.png" class="rich_pages wxw-img" data-ratio="0.1925925925925926" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="100000561"> </section> <ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%22u0cef716e%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22ua5a08470%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E6%8E%A5%E4%B8%8B%E6%9D%A5%E8%BE%93%E5%85%A5%22%7D%2C%7B%22type%22%3A%22element%22%2C%22id%22%3A%22u12324012%22%2C%22name%22%3A%22code%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u0ae40b08%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A14%7D%2C%22data%22%3A%22thread%20-n%201%22%7D%5D%7D%2C%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u5a90496d%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%EF%BC%8C%E8%A1%A8%E7%A4%BA%E6%9C%80%E5%BF%99%E7%9A%84%E7%BA%BF%E7%A8%8B%E5%B9%B6%E6%89%93%E5%8D%B0%E4%BF%A1%E6%81%AF%22%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">接下来输入</span></span><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">thread -n 1</span></span></code><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">,表示最忙的线程并打印信息</span></span></p> <section style="text-align: center;" nodeleaf=""> <img src="/upload/70b151164fbc3d1a7ac6405d6d11e935.png" class="rich_pages wxw-img" data-ratio="0.1685185185185185" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="100000562"> </section> <ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%22uc738d1c7%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22uc5f4a49b%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E4%BB%8E%E4%B8%8A%E9%9D%A2%E7%9A%84%E5%9B%BE%E4%B8%AD%E5%8F%AF%E4%BB%A5%E7%9C%8B%E5%88%B0arthas%E5%92%8Cjstack%E5%B1%95%E7%A4%BA%E7%9A%84%E4%BF%A1%E6%81%AF%E5%B7%AE%E4%B8%8D%E5%A4%9A%EF%BC%8C%E9%83%BD%E5%AE%9A%E4%BD%8D%E5%88%B0%E4%BA%86%22%7D%2C%7B%22type%22%3A%22element%22%2C%22id%22%3A%22u97799645%22%2C%22name%22%3A%22code%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u2ada2ae5%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A14%7D%2C%22data%22%3A%22JVMCPU.java%22%7D%5D%7D%2C%7B%22type%22%3A%22text%22%2C%22id%22%3A%22ud5a90fda%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(36%2C%2041%2C%2046)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E7%9A%8416%E8%A1%8C%E7%A8%8B%E5%BA%8F%22%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fkdotyfqesdqxhh8o"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">从上面的图中可以看到arthas和jstack展示的信息差不多,都定位到了</span></span><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(36, 41, 46);font-size: 14px;"><span leaf="">JVMCPU.java</span></span></code><span style="color: rgb(36, 41, 46);font-size: 16px;"><span leaf="">的16行程序</span></span></p>
作者:微信小助手
<article> <h2 yne-bulb-block="heading" yne-bulb-level="2" style="white-space:pre-wrap;line-height:1.75;font-size:14px;text-align:left;"><span style="font-weight: bold;font-size: 20px;"><span leaf="">1. 什么是深度分页</span></span></h2> <p><span style="color: rgb(243, 50, 50);"><span leaf="">深度分页是指在处理大数据集查询时,用户尝试访问多页数据中较后面的页面时遇到的问题</span></span><span leaf="">。当尝试访问排序后的数据列表的第1000页或更后面的页面时,数据库需要先跳过前面数十万条记录,这一过程通常涉及大量的数据扫描和排序,极大地增加了数据库的查询负载,从而成为性能瓶颈。</span></p> <p><span leaf="">ES分页查询流程大致如下:</span></p> <ol style="margin:0px;margin-left: 14px;" class="list-paddingleft-1"> <li> <section> <span leaf="">数据存储在各个分片中,协调节点将查询请求转发给各个节点,当各个节点执行搜索后,将排序后的前N条数据返回给协调节点。</span> </section></li> <li> <section> <span leaf="">协调节点汇总各个分片返回的数据,再次排序,最终返回前N条数据给客户端。</span> </section></li> <li> <section> <span leaf="">这个流程会导致一个深度分页的问题,也就是翻页越多,性能越差,甚至导致ES出现OOM。</span> </section></li> </ol> <p><span style="color: rgb(243, 50, 50);"><span leaf="">在分布式系统中,对结果排序的成本随分页的深度成指数上升。</span></span></p> <p><span leaf="">从10万名高考生中查询成绩为的10001-10100位的100名考生的信息。</span></p> <section nodeleaf=""> <img src="/upload/c2120a9e540183a1b8e6a807c3188baa.png" class="rich_pages wxw-img" data-ratio="0.5971143174250833" data-type="png" data-w="901" height="384" style="width: 629px;height: 384px;" width="629" data-imgfileid="100000297"> </section> <p><span leaf="">从上面案例中不难看出,每次有序的查询都会在每个分片中执行单独的查询,然后进行数据的二次排序,而这个二次排序的过程是发生在heap中的,也就是说当你单次查询的数量越大,那么堆内存中汇总的数据也就越多,对内存的压力也就越大。这里的单次查询的数据量取决于你查询的是第几条数据而不是查询了几条数据,比如你希望查询的是第10001-10100这一百条数据,但是ES必须将前10100全部取出进行二次查询。因此,</span><span style="color: rgb(243, 50, 50);"><span leaf="">如果查询的数据排序越靠后,就越容易导致OOM(Out Of Memory)情况的发生,频繁的深分页查询会导致频繁的FullGC。</span></span></p> <p><span style="color: rgb(77, 77, 77);background-color: rgb(255, 255, 255);font-size: 14px;font-family: Arial;"><span leaf="">ES为了避免用户在不了解其内部原理的情况下而做出错误的操作,设置了一个阈值,即</span></span><span style="font-size: 14px;"><span leaf="">max_result_window</span></span><span style="color: rgb(77, 77, 77);background-color: rgb(255, 255, 255);font-size: 14px;font-family: Arial;"><span leaf="">,其默认值为</span></span><span style="font-size: 14px;"><span leaf="">10000</span></span><span style="color: rgb(77, 77, 77);background-color: rgb(255, 255, 255);font-size: 14px;font-family: Arial;"><span leaf="">,</span></span><span style="color: rgb(243, 50, 50);background-color: rgb(255, 255, 255);font-size: 14px;font-family: Arial;"><span leaf="">其作用是为了保护堆内存不被错误操作导致溢出。</span></span></p> <p><span style="font-weight: bold;"></span></p> <h2 yne-bulb-block="heading" yne-bulb-level="2" style="white-space:pre-wrap;line-height:1.75;font-size:14px;text-align:left;"><span style="font-weight: bold;font-size: 20px;"><span leaf="">2. 深度分页不推荐使用from+size</span></span></h2> <p><span leaf="">在Elasticsearch中,分页查询的实现主要通过两个参数from和size来实现。from参数指定了从结果集中的第几条数据开始返回,而size参数指定了返回数据的数量。正常情况下分页代码如实下面这样的:</span></p> </article> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="css"><code><span leaf=""><span class="code-snippet__plaintext"># 查询第一页</span><span class="code-snippet__number">5</span><span class="code-snippet__plaintext">条数据</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">GET /employee/_search</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">{</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> "query": {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> "match_all": {}</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> },</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> "</span><span class="code-snippet__selector-tag">from</span><span class="code-snippet__plaintext">": </span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"size"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">5</span><span class="code-snippet__plaintext"> </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">}</span></span></code></pre> </section> <article> <p><span leaf="">输出结果如下图:</span></p> <section nodeleaf=""> <img src="/upload/43a8784098ea2c6fad05cf20d685d27d.png" class="rich_pages wxw-img" data-ratio="1.4823529411764707" data-type="png" data-w="340" height="504" style="width: 340px;height: 504px;" width="340" data-imgfileid="100000299"> </section> <p><span leaf="">但是如果我们查询的数据页数特别大,当from + size大于10000的时候,就会出现问题,如下图报错信息所示:</span></p> <section nodeleaf=""> <img src="/upload/a3c241dc22dd8dfbad2fa510b0684b15.png" class="rich_pages wxw-img" data-ratio="0.28055555555555556" data-type="png" data-w="1080" height="503" style="width: 1794px;height: 503px;" width="1794" data-imgfileid="100000300"> </section> <p><span leaf="">分析可知,查询结果的窗口大小超过了最大窗口的限制,而index. max_result_window默认值为10000。</span></p> <p><span style="color: rgb(243, 50, 50);"><span leaf="">Elasticsearch会限制最大分页数,避免因大数据量的召回导致系统性能低下。</span></span><span leaf="">Elasticsearch的max_result_window默认值是10000,意味着每页有10条数据,会最大翻页至1000页。主流搜索引擎实际都翻不了那么多页。</span></p> <p><span leaf="">对此,有两个可行的解决方案,如下所示:</span></p> <ul style="margin:0px;margin-left: 14px;" class="list-paddingleft-1"> <li> <section> <span leaf="">方案一:对于大型数据集,我们可采用scroll API来召回数据。这个策略我们将在后续的内容中进行详细分析。</span> </section></li> <li> <section> <span leaf="">方案二:调大index.max_result_window默认值</span> </section></li> </ul> </article> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="bash"><code><span leaf=""><span class="code-snippet__plaintext">PUT /employee/_settings</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">{</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"index.max_result_window"</span><span class="code-snippet__plaintext">: 20000</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">}</span></span></code></pre> </section> <article> <p><span style="color: rgb(243, 50, 50);"><span leaf="">官方建议避免使用from+size来过度分页或一次请求太多结果。</span></span></p> <p><span leaf="">不推荐使用from+size来深度分页的核心原因如下:</span></p> <ul style="margin:0px;margin-left: 14px;" class="list-paddingleft-1"> <li> <section> <span leaf="">搜索请求通常会跨多个分片,每个分片必须将其请求的命中内容以及先前页面的命中内容加载到内存中。</span> </section></li> <li> <section> <span leaf="">对于分页较多的页面或大量结果,这样操作会显著增加内存和CPU使用率,导致性能下降,甚至导致节点故障。</span> </section></li> </ul> <h3 yne-bulb-block="heading" yne-bulb-level="3" style="white-space:pre-wrap;line-height:1.75;font-size:14px;text-align:left;"><span style="font-weight: bold;font-size: inherit;"><span leaf="">from+size查询的优缺点及适用场景</span></span></h3> <p><span leaf="">from+size分页查询的优缺点如下:</span></p> <ul style="margin:0px;margin-left: 14px;" class="list-paddingleft-1"> <li> <section> <span leaf="">from+size查询优点:支持随机翻页。</span> </section></li> <li> <section> <span leaf="">from+size查询缺点:</span> </section></li> </ul> <p><span leaf="">from+size查询适用场景如下:</span></p> <ul style="margin:0px;margin-left: 14px;" class="list-paddingleft-1"> <li> <section> <span leaf="">非常适合小型数据集或者从大数据集中返回Top N(N≤10000)结果集的业务场景。</span> </section></li> <li> <section> <span leaf="">主流PC搜索引擎中支持随机跳转分页的业务场景,如下图所示:</span> </section></li> </ul> <section nodeleaf=""> <img src="/upload/35afb1f9a0f31cf69522060219414d2b.png" class="rich_pages wxw-img" data-ratio="0.5305389221556887" data-type="png" data-w="835" height="443" style="width: 835px;height: 443px;" width="835" data-imgfileid="100000302"> </section> <p><span style="color: rgb(243, 50, 50);background-color: rgb(255, 255, 255);font-size: 14px;font-family: Arial;"></span></p> <h2 yne-bulb-block="heading" yne-bulb-level="2" style="white-space:pre-wrap;line-height:1.75;font-size:14px;text-align:left;"><span style="font-weight: bold;font-size: 20px;"><span leaf="">3</span></span><span style="font-weight: bold;font-size: 20px;"><span leaf="">.</span></span><span style="font-weight: bold;font-size: 20px;"><span leaf="">深度分页问题的常见解决方案</span></span></h2> <h3 yne-bulb-block="heading" yne-bulb-level="3" style="white-space:pre-wrap;line-height:1.75;font-size:14px;text-align:left;"><span style="font-weight: bold;font-size: inherit;"><span leaf="">尝试避免使用深度分页</span></span></h3> <p><span style="color: rgb(243, 50, 50);"><span leaf="">解决深度分页问题最好的办法就是避免使用深度分页。</span></span><span style="color: rgb(77, 77, 77);background-color: rgb(255, 255, 255);font-family: Arial;"><span leaf="">谷歌、</span></span><span style="background-color: rgb(255, 255, 255);font-family: Arial;"><span leaf="">百度</span></span><span style="color: rgb(77, 77, 77);background-color: rgb(255, 255, 255);font-family: Arial;"><span leaf="">目前作为全球和国内做大的搜索引擎不约而同的在分页条中</span></span><span style="color: rgb(243, 50, 50);background-color: rgb(255, 255, 255);font-family: Arial;"><span leaf="">删除了“</span></span><span style="color: rgb(243, 50, 50);"><span leaf="">跳页</span></span><span style="color: rgb(243, 50, 50);background-color: rgb(255, 255, 255);font-family: Arial;"><span leaf="">”功能</span></span><span style="color: rgb(77, 77, 77);background-color: rgb(255, 255, 255);font-family: Arial;"><span leaf="">,其目的就是为了避免用户使用深度分页检索。</span></span></p> <section nodeleaf=""> <img src="/upload/35afb1f9a0f31cf69522060219414d2b.png" class="rich_pages wxw-img" data-ratio="0.5305389221556887" data-type="png" data-w="835" height="337" style="width: 606px;height: 337px;" width="606" data-imgfileid="100000303"> </section> <p><span leaf="">在百度中搜索“Elasticsearch”,在搜索结果中翻到第20页,就无法再往下翻页了,提示信息如下图:</span></p> <section nodeleaf=""> <img src="/upload/f467a6ed1710cb89b0d3cefa94944426.png" class="rich_pages wxw-img" data-ratio="0.6416666666666667" data-type="png" data-w="1080" height="835" style="width: 1302px;height: 835px;" width="1302" data-imgfileid="100000305"> </section> <p><span style="text-decoration: underline;color: rgb(3, 102, 214);"><span leaf="">淘宝</span></span><span leaf="">虽然没有删除“跳页”功能,但不管我们搜索什么内容,只要商品结果足够多,返回的商品列表都是仅展示前100页的数据,其本质和ES中的max_result_window作用是一样的,都是限制你去搜索更深页数的数据。</span></p> <section nodeleaf=""> <img src="/upload/25371c2068d4ba8a79fbad862105497a.png" class="rich_pages wxw-img" data-ratio="0.3522727272727273" data-type="png" data-w="1056" height="266" style="width: 752px;height: 266px;" width="752" data-imgfileid="100000304"> </section> <p><span leaf="">手机端APP就更不用说了,直接是下拉加载更多,连分页条都没有,相当于你只能点击“下一页”。</span></p> <h3 yne-bulb-block="heading" yne-bulb-level="3" style="white-space:pre-wrap;line-height:1.75;font-size:14px;text-align:left;"><span style="font-weight: bold;font-size: inherit;"><span leaf="">Scroll Search</span></span><span style="font-weight: bold;font-size: inherit;"><span leaf="">滚动查询</span></span></h3> <p><span style="color: rgb(243, 50, 50);"><span leaf="">scroll API可从单个搜索请求中检索大量结果(甚至所有结果)</span></span><span leaf="">,这种方式与传统数据库中的游标(cursor)类似。</span><span style="color: rgb(243, 50, 50);"><span leaf="">scroll滚动遍历查询是非实时的</span></span><span leaf="">,数据量大的时候,响应时间可能会比较长。</span></p> <blockquote> <p><span leaf="">官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/8.14/paginate-search-results.html#scroll-search-results</span></p> </blockquote> <p><span style="color: rgb(243, 50, 50);"><span leaf="">ES7之后,官方已经不再建议使用scroll API进行深度分页。</span></span><span leaf="">如果要分页检索超过 Top 10,000+ 结果时,推荐使用:search_after。</span></p> <section nodeleaf=""> <img src="/upload/f8121780f02a53f94014c7bb71e5bba0.png" class="rich_pages wxw-img" data-ratio="0.12488350419384903" data-type="png" data-w="1073" height="134" style="width: 1073px;height: 134px;" width="1073" data-imgfileid="100000301"> </section> <p><span style="font-weight: bold;"><span leaf="">适合场景</span></span></p> <p><span leaf="">单个滚动搜索请求中检索大量结果,即非“C端业务”场景</span></p> <h4 yne-bulb-block="heading" yne-bulb-level="4" style="white-space:pre-wrap;line-height:1.75;font-size:14px;text-align:left;"><span style="font-weight: bold;"><span leaf="">实现步骤</span></span></h4> <p><span leaf="">scroll查询的核心执行步骤如下。</span></p> <p><span style="font-weight: bold;"><span leaf="">1) 第一次进行scroll查询,指定检索语句的同时设置scroll上下文保留时间。</span></span></p> <p><span leaf="">scroll请求返回的结果反映了发出初始搜索请求时索引的状态,就像在那一个时刻做了快照,随后对文档的更改(写入、更新或删除)只会影响以后的搜索请求。</span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="swift"><code><span leaf=""><span class="code-snippet__plaintext"># 使用kibana提供的航班测试数据集</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">#查询命令中新增scroll</span><span class="code-snippet__operator">=</span><span class="code-snippet__plaintext">5m,说明采用游标查询,保持游标查询窗口</span><span class="code-snippet__number">5</span><span class="code-snippet__plaintext">分钟,也就是本次快照的结果缓存起来的有效时间是</span><span class="code-snippet__number">5</span><span class="code-snippet__plaintext">分钟</span><span class="code-snippet__operator">。</span></span></code><code><span leaf=""><span class="code-snippet__type">GET</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__regexp">/kibana_sample_data_flights/</span><span class="code-snippet__plaintext">_search</span><span class="code-snippet__operator">?</span><span class="code-snippet__plaintext">scroll</span><span class="code-snippet__operator">=</span><span class="code-snippet__plaintext">5m </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">{</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"query"</span><span class="code-snippet__plaintext">: {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"term"</span><span class="code-snippet__plaintext">: {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"OriginWeather"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"Sunny"</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> }</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> },</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"size"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">100</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">}</span></span></code></pre> </section> <p><span leaf=""><br></span></p> </article> <article data-content="[{"type":"block","id":"5759-1652538006122","name":"paragraph","data":{"version":1},"nodes":[{"type":"text","id":"BfrC-1688026638080","leaves":[{"text":"返回结果:","marks":[]}]}],"state":{}},{"type":"block","id":"Zkdh-1723984881982","name":"image","data":{"version":1,"url":"https://note.youdao.com/yws/res/f/WEBRESOURCEd42f7ebf11466088efe7cce6fa0b5e4f","width":949,"height":443,"fromIdentity":""},"nodes":[],"state":{"renderSource":"https://note.youdao.com/yws/res/f/WEBRESOURCEd42f7ebf11466088efe7cce6fa0b5e4f","initialSize":{"width":949,"height":443},"loading":false}},{"type":"block","id":"8381-1652538006122","name":"paragraph","data":{"version":1},"nodes":[{"type":"text","id":"PIsS-1688026638080","leaves":[{"text":"2) 向后翻页,继续获取数据,直到没有要返回的结果为止","marks":[{"type":"bold"}]}]}],"state":{}}]"> <p><span leaf="">返回结果:</span></p> <section nodeleaf=""> <img src="/upload/6cc1f04accb3292c1593e8d08414561b.png" class="rich_pages wxw-img" data-ratio="0.46680716543730244" data-type="png" data-w="949" height="443" style="width: 949px;height: 443px;" width="949" data-imgfileid="100000306"> </section> <p><span style="font-weight: bold;"><span leaf="">2) 向后翻页,继续获取数据,直到没有要返回的结果为止</span></span></p> </article> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="swift"><code><span leaf=""><span class="code-snippet__plaintext"># scroll_id 的值就是上一个请求中返回的 _scroll_id 的值</span></span></code><code><span leaf=""><span class="code-snippet__type">GET</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__regexp">/_search/</span><span class="code-snippet__plaintext">scroll</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">{</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"scroll"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"5m"</span><span class="code-snippet__plaintext">, </span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"scroll_id"</span><span class="code-snippet__plaintext"> : </span><span class="code-snippet__string">"FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFnQ5MUF6M3dYUkhPQW81czY3RXBDckEAAAAAABkMUBZPOVotS1A1MlI1dU43QXFsdkRGUEhB"</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">}</span></span></code></pre> </section> <article data-content="[{"type":"block","id":"7mwv-1723984783507","name":"paragraph","data":{"version":1},"nodes":[{"type":"text","id":"VeJU-1723984783506","leaves":[{"text":"多次根据scroll_id游标查询,直到没有数据返回则结束查询。采用游标查询索引全量数据,更安全高效,限制了单次对内存的消耗。","marks":[]}]}],"state":{}},{"type":"block","id":"9263-1653830250250","name":"paragraph","data":{"version":1},"nodes":[{"type":"text","id":"GPxi-1688026638081","leaves":[{"text":"删除游标scroll","marks":[{"type":"bold"}]}]}],"state":{}},{"type":"block","id":"iIR2-1689926903006","name":"paragraph","data":{"version":1},"nodes":[{"type":"text","id":"ASfG-1689926903004","leaves":[{"text":"scroll超过超时后,搜索上下文会自动删除。然而,保持scroll打开是有代价的,因此一旦不再使用,就应明确清除scroll上下文","marks":[]}]}],"state":{}}]"> <p><span leaf="">多次根据scroll_id游标查询,直到没有数据返回则结束查询。采用游标查询索引全量数据,更安全高效,限制了单次对内存的消耗。</span></p> <p><span style="font-weight: bold;"><span leaf="">删除游标scroll</span></span></p> <p><span leaf="">scroll超过超时后,搜索上下文会自动删除。然而,保持scroll打开是有代价的,因此一旦不再使用,就应明确清除scroll上下文</span></p> </article> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="bash"><code><span leaf=""><span class="code-snippet__plaintext">DELETE /_search/scroll</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">{</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"scroll_id"</span><span class="code-snippet__plaintext"> : </span><span class="code-snippet__string">"FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFmNwcVdjblRxUzVhZXlicG9HeU02bWcAAAAAAABmzRY2YlV3Z0o5VVNTdWJobkE5Z3MtXzJB"</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">}</span></span></code></pre> </section> <article> <h4 yne-bulb-block="heading" yne-bulb-level="4" style="white-space:pre-wrap;line-height:1.75;font-size:14px;text-align:left;"><span style="font-weight: bold;"><span leaf="">scroll查询的优缺点及适用场景</span></span></h4> <p><span style="font-weight: bold;"><span leaf="">scroll查询的优缺点如下:</span></span></p> <ul style="margin:0px;margin-left: 14px;" class="list-paddingleft-1"> <li><span style="font-weight: bold;"><span leaf="">scroll查询优点:</span></span> <section> <span leaf="">支持全量遍历,是检索大量文档的重要方法,但单次遍历的size值不能超过max_result_window的大小。</span> </section></li> <li><span style="font-weight: bold;"><span leaf="">scroll查询缺点:</span></span></li> </ul> <p><span leaf="">scroll查询的适用场景如下:</span></p> <ul style="margin:0px;margin-left: 14px;" class="list-paddingleft-1"> <li> <section> <span leaf="">大量文档检索:当要检索的文档数量很大,甚至需要全量召回数据时,scroll查询是一个很好的选择。</span> </section></li> <li> <section> <span leaf="">大量文档的数据处理:滚动API适合对大量文档进行数据处理,例如索引迁移或将数据导入其他技术栈。</span> </section></li> </ul> <p><span style="color: rgb(243, 50, 50);"><span leaf="">注意:</span></span></p> <p><span leaf="">1) ES7.x之后不建议使用scroll API进行深度分页。</span></p> <p><span leaf="">2) 如果要分页检索并获得超过10000条结果时,则推荐使用search_after。</span></p> <p><span leaf=""><br></span></p> <p><span style="color: rgb(243, 50, 50);"></span></p> <h3 yne-bulb-block="heading" yne-bulb-level="3" style="white-space:pre-wrap;line-height:1.75;font-size:14px;text-align:left;"><span style="font-weight: bold;font-size: inherit;"><span leaf="">search_after查询</span></span></h3> <p><span style="color: rgb(243, 50, 50);"><span leaf="">search_after查询的基本工作原理是以前一页结果的排序值作为参照点,进而检索与这个参照点相邻的下一页的匹配数据。</span></span></p> <p><span leaf="">这种方法在处理大规模数据分页时更为高效且实用。使用该查询的前置条件是要求后续的多个请求返回与第一次查询相同的排序结果序列。也就是说,</span><span style="color: rgb(243, 50, 50);"><span leaf="">在后续翻页的过程中,即便有新数据写入等操作,也不会对原有结果集构成影响。</span></span></p> <p><span leaf="">scroll API适用于高效的深度滚动,但滚动上下文成本高昂,不建议将其用于实时用户请求。而search_after参数通过提供一个活动光标来规避这个问题。这样可以使用上一页的结果来帮助检索下一页。</span></p> <blockquote> <p><span leaf="">官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/8.14/paginate-search-results.html#search-after</span></p> </blockquote> <p><span leaf="">那么,如何实现呢?</span></p> <p><span style="color: rgb(243, 50, 50);"><span leaf="">可以创建一个时间点PIT(Point In Time)来保障在搜索过程中能保留特定事件点的索引状态。</span></span><span leaf="">search_after的后续查询都是基于PIT视图进行的,能有效保障数据的一致性。</span></p> <article data-content="[{"type":"block","id":"eaRk-1723981478698","name":"quote","data":{},"nodes":[{"type":"block","id":"nLBF-1723981475121","name":"paragraph","data":{},"nodes":[{"type":"text","id":"RayY-1723981475119","leaves":[{"text":"PIT是Elasticsearch 7.10版本之后才有的新特性,实际上是存储索引数据状态的轻量级视图。","marks":[]}]}]}],"state":{}},{"type":"block","id":"lu8d-1723981395188","name":"paragraph","data":{"version":1},"nodes":[{"type":"text","id":"y7WA-1723981395187","leaves":[{"text":"","marks":[]}]}],"state":{}}]"> <p><span leaf="">PIT是Elasticsearch 7.10版本之后才有的新特性,实际上是存储索引数据状态的轻量级视图。</span></p> <p><span leaf=""><br></span></p> </article> </article> <article> <h4 yne-bulb-block="heading" yne-bulb-level="4" style="white-space:pre-wrap;line-height:1.75;font-size:14px;text-align:left;"><span style="font-weight: bold;"><span leaf="">实现步骤</span></span></h4> <p><span leaf="">search_after 分页查询可以简单概括为如下几个步骤:</span></p> <p><span style="font-weight: bold;"><span leaf="">1)获取索引的pit</span></span></p> <p><span leaf="">使用 search_after 需要具有相同查询和排序值的多个搜索请求。 如果在这些请求之间发生刷新,结果的顺序可能会发生变化,从而导致跨页面的结果不一致。 为防止出现这种情况,</span><span style="color: rgb(243, 50, 50);"><span leaf="">可以创建一个时间点 (PIT) 以保留搜索中的当前索引状态</span></span><span leaf="">。Point In Time(PIT)是 Elasticsearch 7.10 版本之后才有的新特性</span><span style="color: rgb(77, 77, 77);background-color: rgb(255, 255, 255);font-family: Arial;"><span leaf="">。</span></span></p> </article> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="swift"><code><span leaf=""><span class="code-snippet__plaintext"># 使用kibana提供的航班测试数据集</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"># 创建一个时间点(</span><span class="code-snippet__type">PIT</span><span class="code-snippet__plaintext">)来保存搜索期间的当前索引状态</span></span></code><code><span leaf=""><span class="code-snippet__type">POST</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__regexp">/kibana_sample_data_flights/</span><span class="code-snippet__plaintext">_pit</span><span class="code-snippet__operator">?</span><span class="code-snippet__plaintext">keep_alive</span><span class="code-snippet__operator">=</span><span class="code-snippet__plaintext">5m</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">#返回结果如下,会返回一个</span><span class="code-snippet__type">PID的值</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">{</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"4YyPBAEaa2liYW5hX3NhbXBsZV9kYXRhX2ZsaWdodHMWZENSdWh0NWNSai1EdUhpcnBCZXgyZwAWTzlaLUtQNTJSNXVON0FxbHZERlBIQQAAAAAAABkI4hZ0OTFBejN3WFJIT0FvNXM2N0VwQ3JBAAEWZENSdWh0NWNSai1EdUhpcnBCZXgyZwAA"</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">}</span></span></code></pre> </section> <article> <p><span leaf="">keep_alive=5m是一个类似于scroll的参数,表示滚动视图的保留时间是5min,超过5min Elasticsearch会清除这个滚动视图并报错,如下图所示</span></p> <section nodeleaf=""> <img src="/upload/ddd38ae024262b610c874005b6459e3e.png" class="rich_pages wxw-img" data-ratio="0.2078740157480315" data-type="png" data-w="635" height="132" style="width: 635px;height: 132px;" width="635" data-imgfileid="100000307"> </section> <p><span style="color: rgb(77, 77, 77);background-color: rgb(255, 255, 255);font-size: 14px;font-family: Arial;font-weight: bold;"><span leaf="">2) 根据pit首次查询</span></span></p> <p><span leaf="">创建基础查询语句,主要是设置分页的条件</span></p> </article> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="bash"><code><span leaf=""><span class="code-snippet__plaintext">GET /_search</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">{</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"query"</span><span class="code-snippet__plaintext">: {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"term"</span><span class="code-snippet__plaintext">: {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"OriginWeather"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"Sunny"</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> }</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> },</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"pit"</span><span class="code-snippet__plaintext">: {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"4YyPBAEaa2liYW5hX3NhbXBsZV9kYXRhX2ZsaWdodHMWZENSdWh0NWNSai1EdUhpcnBCZXgyZwAWTzlaLUtQNTJSNXVON0FxbHZERlBIQQAAAAAAABkI4hZ0OTFBejN3WFJIT0FvNXM2N0VwQ3JBAAEWZENSdWh0NWNSai1EdUhpcnBCZXgyZwAA"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"keep_alive"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"1m"</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> },</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"size"</span><span class="code-snippet__plaintext">: 10,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"sort"</span><span class="code-snippet__plaintext">: [</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"timestamp"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"asc"</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> }</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> ]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">}</span></span></code></pre> </section> <article> <p><span leaf="">代码中设置了PIT,因此检索时候就不需要再指定索引。id是基于第一步返回的id值。排序sort指的是按照哪个关键字排序。</span></p> <p><span leaf="">在每个返回文档的最后会有两个结果值,如下所示:</span></p> <section nodeleaf=""> <img src="/upload/9a4cf81d52a8bd62480279d2c4951618.png" class="rich_pages wxw-img" data-ratio="0.20469798657718122" data-type="png" data-w="596" height="122" style="width: 596px;height: 122px;" width="596" data-imgfileid="100000308"> </section> <p><span leaf="">在每个返回文档的最后会有两个结果值,如下所示。</span></p> <p><span leaf="">其中,1723434063000就是我们指定的排序方式,所以上述示例是基于{"timestamp": "asc"}升序排列的。130代表隐含的排序值,官方文档把这种隐含的字段叫作tiebreaker(决胜字段),tiebreaker代表了每个文档的唯一值,确保分页不会丢失或者分页结果数据出现重复(包括相同页重复和跨页重复)。</span></p> <p><span style="color: rgb(77, 77, 77);background-color: rgb(255, 255, 255);font-size: inherit;font-family: Arial;font-weight: bold;"><span leaf="">3)</span></span><span style="font-size: inherit;font-weight: bold;"><span leaf="">根据search_after和pit实现后续翻页。</span></span></p> <p><span leaf="">要获得下一页结果,请使用最后一次命中的排序值(包括 tiebreaker)作为 search_after 参数重新运行先前的搜索。 如果使用 PIT,请在 pit.id 参数中使用最新的 PIT ID。 搜索的查询和排序参数必须保持不变。</span></p> </article> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="cpp"><code><span leaf=""><span class="code-snippet__plaintext">#后续翻页都需要借助search_after来指定前一页中最后一个文档的sort字段值</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">GET /_search</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">{</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"query"</span><span class="code-snippet__plaintext">: {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"term"</span><span class="code-snippet__plaintext">: {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"OriginWeather"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"Sunny"</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> }</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> },</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"pit"</span><span class="code-snippet__plaintext">: {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"4YyPBAEaa2liYW5hX3NhbXBsZV9kYXRhX2ZsaWdodHMWZENSdWh0NWNSai1EdUhpcnBCZXgyZwAWTzlaLUtQNTJSNXVON0FxbHZERlBIQQAAAAAAABkI4hZ0OTFBejN3WFJIT0FvNXM2N0VwQ3JBAAEWZENSdWh0NWNSai1EdUhpcnBCZXgyZwAA"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"keep_alive"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"5m"</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> },</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"size"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">10</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"sort"</span><span class="code-snippet__plaintext">: [</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"timestamp"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"asc"</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> }</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> ],</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"search_after"</span><span class="code-snippet__plaintext">: [</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">1723434063000</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">130</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> ]</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">}</span></span></code></pre> </section> <article> <p><span style="color: rgb(243, 50, 50);"><span leaf="">显然,search_after查询仅支持向后翻页。</span></span></p> <h4 yne-bulb-block="heading" yne-bulb-level="4" style="white-space:pre-wrap;line-height:1.75;font-size:14px;text-align:left;"><span style="font-weight: bold;"><span leaf="">优缺点</span></span></h4> <p><span style="font-weight: bold;"><span leaf="">search_after优点:</span></span></p> <ul style="margin:0px;margin-left: 14px;" class="list-paddingleft-1"> <li> <section> <span leaf="">不严格受制于max_result_window,可以无限地往后翻页。此处的“不严格”是指单次请求值不能超过max_result_window,但总翻页结果集可以超过。</span> </section></li> </ul> <p><span style="font-weight: bold;"><span leaf="">search_after缺点:</span></span></p> <ul style="margin:0px;margin-left: 14px;" class="list-paddingleft-1"> <li> <section> <span leaf="">只支持向后翻页,不支持随机翻页。search_after不支持随机翻页,更适合在手机端应用的场景中使用,类似今日头条等产品的分页搜索。</span> </section></li> </ul> <p><span style="color: rgb(77, 77, 77);background-color: rgb(255, 255, 255);font-size: inherit;font-family: Arial;"></span></p> <h2 yne-bulb-block="heading" yne-bulb-level="2" style="white-space:pre-wrap;line-height:1.75;font-size:14px;text-align:left;"><span style="font-weight: bold;font-size: 20px;"><span leaf="">4. ES三种分页方式总结</span></span></h2> <table style="border-collapse:collapse;table-layout:fixed;white-space:nowrap;width:0;"> <caption> <section> <span leaf=""><br></span> </section> </caption> <tfoot> <tr> <td valign="top"> <section> <span leaf=""><br></span> </section></td> </tr> </tfoot> </table> <table> <tbody> <tr style="height: 40px;"> <td valign="top" style="background-color:rgb(240, 240, 240);border:1px solid rgb(167, 167, 167);overflow:hidden;font-size:14px;overflow-wrap:break-word;white-space:pre-wrap;color:rgb(57, 57, 57);"><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">分页方式</span></span></p></td> <td valign="top" style="background-color:rgb(240, 240, 240);border:1px solid rgb(167, 167, 167);overflow:hidden;font-size:14px;overflow-wrap:break-word;white-space:pre-wrap;color:rgb(57, 57, 57);"><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">性能</span></span></p></td> <td valign="top" style="background-color:rgb(240, 240, 240);border:1px solid rgb(167, 167, 167);overflow:hidden;font-size:14px;overflow-wrap:break-word;white-space:pre-wrap;color:rgb(57, 57, 57);"><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">优点</span></span></p></td> <td valign="top" style="background-color:rgb(240, 240, 240);border:1px solid rgb(167, 167, 167);overflow:hidden;font-size:14px;overflow-wrap:break-word;white-space:pre-wrap;color:rgb(57, 57, 57);"><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">缺点</span></span></p></td> <td valign="top" style="background-color:rgb(240, 240, 240);border:1px solid rgb(167, 167, 167);overflow:hidden;font-size:14px;overflow-wrap:break-word;white-space:pre-wrap;color:rgb(57, 57, 57);"><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">适用场景</span></span></p></td> </tr> <tr style="height: 40px;"> <td valign="top" style="border:1px solid rgb(167, 167, 167);overflow:hidden;font-size:14px;overflow-wrap:break-word;white-space:pre-wrap;color:rgb(57, 57, 57);"><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">from + size</span></span></p></td> <td valign="top" style="border:1px solid rgb(167, 167, 167);overflow:hidden;font-size:14px;overflow-wrap:break-word;white-space:pre-wrap;color:rgb(57, 57, 57);"><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">低</span></span></p></td> <td valign="top" style="border:1px solid rgb(167, 167, 167);overflow:hidden;font-size:14px;overflow-wrap:break-word;white-space:pre-wrap;color:rgb(57, 57, 57);"><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">支持随机翻页</span></span></p></td> <td valign="top" style="border:1px solid rgb(167, 167, 167);overflow:hidden;font-size:14px;overflow-wrap:break-word;white-space:pre-wrap;color:rgb(57, 57, 57);"><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">受制于max_result_window设置,不能无限制翻页;</span></span></p><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">存在深度翻译问题,越往后翻译越慢。</span></span></p></td> <td valign="top" style="border:1px solid rgb(167, 167, 167);overflow:hidden;font-size:14px;overflow-wrap:break-word;white-space:pre-wrap;color:rgb(57, 57, 57);"><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">需要随机跳转不同页(PC端主流搜索引擎); 在10000条数据之内分页显示</span></span></p></td> </tr> <tr style="height: 78px;"> <td valign="top" style="border:1px solid rgb(167, 167, 167);overflow:hidden;font-size:14px;overflow-wrap:break-word;white-space:pre-wrap;color:rgb(57, 57, 57);"><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">scroll</span></span></p></td> <td valign="top" style="border:1px solid rgb(167, 167, 167);overflow:hidden;font-size:14px;overflow-wrap:break-word;white-space:pre-wrap;color:rgb(57, 57, 57);"><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">中</span></span></p></td> <td valign="top" style="border:1px solid rgb(167, 167, 167);overflow:hidden;font-size:14px;overflow-wrap:break-word;white-space:pre-wrap;color:rgb(57, 57, 57);"><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">支持全量遍历,但单次遍历的size值不能超过max_result_window的大小</span></span></p></td> <td valign="top" style="border:1px solid rgb(167, 167, 167);overflow:hidden;font-size:14px;overflow-wrap:break-word;white-space:pre-wrap;color:rgb(57, 57, 57);"><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">响应是非实时的;保留上下文需要具有足够的堆内存空间;需要通过更多的网络请求才能获取所有结果。</span></span></p></td> <td valign="top" style="border:1px solid rgb(167, 167, 167);overflow:hidden;font-size:14px;overflow-wrap:break-word;white-space:pre-wrap;color:rgb(57, 57, 57);"><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">需要遍历全量数据</span></span></p></td> </tr> <tr style="height: 40px;"> <td valign="top" style="border:1px solid rgb(167, 167, 167);overflow:hidden;font-size:14px;overflow-wrap:break-word;white-space:pre-wrap;color:rgb(57, 57, 57);"><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">search_after</span></span></p></td> <td valign="top" style="border:1px solid rgb(167, 167, 167);overflow:hidden;font-size:14px;overflow-wrap:break-word;white-space:pre-wrap;color:rgb(57, 57, 57);"><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">高</span></span></p></td> <td valign="top" style="border:1px solid rgb(167, 167, 167);overflow:hidden;font-size:14px;overflow-wrap:break-word;white-space:pre-wrap;color:rgb(57, 57, 57);"><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">不严格受制于max_result_window,可以无限地往后翻页。</span></span></p></td> <td valign="top" style="border:1px solid rgb(167, 167, 167);overflow:hidden;font-size:14px;overflow-wrap:break-word;white-space:pre-wrap;color:rgb(57, 57, 57);"><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">只支持向后翻页,不支持随机翻页。</span></span></p></td> <td valign="top" style="border:1px solid rgb(167, 167, 167);overflow:hidden;font-size:14px;overflow-wrap:break-word;white-space:pre-wrap;color:rgb(57, 57, 57);"><p><span style="font-family: Microsoft YaHei, STXihei;background-color: rgba(0, 0, 0, 0);font-size: 14px;color: rgb(0, 0, 0);"><span leaf="">仅需要向后翻页;超过10000条数据,需要分页</span></span></p></td> </tr> </tbody> </table> </article>
作者:微信小助手
<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 10px;padding-right: 10px;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;font-family: Optima, 'Microsoft YaHei', PingFangSC-regular, serif;font-size: 16px;color: rgb(0, 0, 0);line-height: 1.5em;word-spacing: 0em;letter-spacing: 0em;word-break: break-word;overflow-wrap: break-word;text-align: left;"> <h1 data-tool="mdnice编辑器" style=" align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: transparent;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: center;line-height: 1.5em;margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px; text-align: left;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset; "><span data-cacheurl="" data-remoteid="" style="background-attachment: scroll;background-clip: border-box;background-color: transparent;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: contain;width: 30px;height: auto;align-items: unset;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;color: rgb(0, 0, 0);display: block;font-size: 22px;font-weight: bold;font-style: normal;flex-direction: unset;float: unset;justify-content: unset;letter-spacing: 0em;line-height: 1.5em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px; text-align: left;text-indent: 0em;text-shadow: none;transform: none;-webkit-box-reflect: unset;background-image: url(" https: mmbiz.qpic.cn sz_mmbiz_png ibyr7oxjrfgx83b9rloaxlqftamoykiaah6ysulvk0tqegnvyggiadwqmng8uffvfkd2obommmpmx0r7muzvqhazw 640?wx_fmt="png&from=appmsg");""></span><span style=" font-size: 22px;line-height: 1.8em;letter-spacing: 0em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 10px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: transparent;background-image: linear-gradient(0deg, rgb(231, 247, 252) 40%, transparent 40%);background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;color: rgb(112, 188, 234);display: block;font-weight: bold;font-style: normal;flex-direction: unset;float: unset;height: auto;justify-content: unset;overflow-x: unset;overflow-y: unset; text-align: left;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset; "><span leaf="">解密主流框架中的Netty应用</span></span><span style="display: none;"></span></h1> <p data-tool="mdnice编辑器" style="color: rgb(0, 0, 0);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;text-indent: 0em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">大家好,今天我要和大家分享一个有趣的话题:那些著名的开源框架是如何使用Netty的。这些年我在研究这些框架源码的过程中,发现了很多精妙的设计。让我们一起来扒一扒他们的"老底"。</span></p> <h2 data-tool="mdnice编辑器" style=" border-bottom-color: rgb(239, 112, 96);margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 2px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: unset;line-height: 1.1em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;color: rgb(255, 255, 255);background-color: rgb(239, 112, 96);line-height: 1.5em;letter-spacing: 0em;align-items: unset;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 3px;border-top-right-radius: 3px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: inline-block;font-weight: bold;flex-direction: unset;float: unset;height: auto;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 5px;overflow-x: unset;overflow-y: unset;padding-top: 3px;padding-bottom: 1px;padding-left: 10px;padding-right: 10px; text-align: left;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset; "><span leaf="">RocketMQ:消息队列的艺术</span></span><span style="display: none;"></span><span style=" border-bottom-color: rgb(239, 235, 233);align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: solid;border-top-width: 1px;border-bottom-width: 36px;border-left-width: 1px;border-right-width: 20px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: transparent;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;color: rgb(0, 0, 0);display: inline-block;font-size: 16px;font-weight: bold;flex-direction: unset;float: unset;height: auto;justify-content: unset;letter-spacing: 0px;line-height: 1.1em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px; text-align: left;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset; "></span></h2> <p data-tool="mdnice编辑器" style="color: rgb(0, 0, 0);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;text-indent: 0em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">先说说RocketMQ。作为阿里开源的消息中间件,它的网络层完全基于Netty构建。为什么这么说?让我给大家看点有意思的代码。</span></p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: block;"><span style="display: none;"></span><span style="font-size: 20px;color: rgb(0, 0, 0);line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: bold;display: block;"><span leaf="">网络层设计</span></span><span style="display: none;"></span></h3> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg axupzvuyfjydeegicmbjgcsrlqhlfivpiaxhiowogar3ktbib4apblgvwdcbwusecab0qus2w0hwhozmc3a48xxxbcmohigunpy 640?wx_fmt="svg&from=appmsg");""></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">class</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">NettyRemotingServer</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">private</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">final</span></span><span leaf=""> ServerBootstrap serverBootstrap;</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">private</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">final</span></span><span leaf=""> EventLoopGroup bossGroup;</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">private</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">final</span></span><span leaf=""> EventLoopGroup workerGroup;</span><br><span leaf=""> </span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">NettyRemotingServer</span></span><span style="line-height: 26px;"><span leaf="">()</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">this</span></span><span leaf="">.serverBootstrap = </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> ServerBootstrap();</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// boss就配一个线程,够用了</span></span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">this</span></span><span leaf="">.bossGroup = </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> NioEventLoopGroup(</span><span style="color: #d19a66;line-height: 26px;"><span leaf="">1</span></span><span leaf="">, </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> ThreadFactoryImpl(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"NettyBossSelector_"</span></span><span leaf="">));</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// worker线程看配置和压力来定</span></span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">this</span></span><span leaf="">.workerGroup = </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> NioEventLoopGroup(</span><br><span leaf=""> NettyServerConfig.getServerWorkerThreads(),</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> ThreadFactoryImpl(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"NettyServerWorkerSelector_"</span></span><span leaf="">)</span><br><span leaf=""> );</span><br><span leaf=""> }</span><br><span leaf="">}</span><br></code></pre> <p data-tool="mdnice编辑器" style="color: rgb(0, 0, 0);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;text-indent: 0em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">有意思的是,RocketMQ把网络层抽象得特别好。记得有次我们要基于RocketMQ做二次开发,就特别感激它这种设计:</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg axupzvuyfjydeegicmbjgcsrlqhlfivpiaxhiowogar3ktbib4apblgvwdcbwusecab0qus2w0hwhozmc3a48xxxbcmohigunpy 640?wx_fmt="svg&from=appmsg");""></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 请求-响应模型</span></span><br><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">class</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">RequestProcessor</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> RemotingCommand </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">processRequest</span></span><span style="line-height: 26px;"><span leaf="">(ChannelHandlerContext ctx, RemotingCommand request)</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 1. 生成请求ID,保证请求唯一性</span></span><br><span leaf=""> request.setOpaque(requestId.getAndIncrement());</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 2. 创建响应Future</span></span><br><span leaf=""> ResponseFuture responseFuture = </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> ResponseFuture(request.getOpaque(),</span><br><span leaf=""> timeoutMillis);</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 3. 发送请求</span></span><br><span leaf=""> channel.writeAndFlush(request);</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 4. 等待响应</span></span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">return</span></span><span leaf=""> responseFuture.waitResponse();</span><br><span leaf=""> }</span><br><span leaf="">}</span><br></code></pre> <p data-tool="mdnice编辑器" style="color: rgb(0, 0, 0);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;text-indent: 0em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">RocketMQ的这套设计教会我们:</span></p> <ol style="list-style-type: decimal;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">网络层要做好抽象,方便扩展</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">请求-响应要支持超时和异步</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">连接管理要做到优雅和高效</span> </section></li> </ol> <h2 data-tool="mdnice编辑器" style=" border-bottom-color: rgb(239, 112, 96);margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 2px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: unset;line-height: 1.1em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;color: rgb(255, 255, 255);background-color: rgb(239, 112, 96);line-height: 1.5em;letter-spacing: 0em;align-items: unset;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 3px;border-top-right-radius: 3px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: inline-block;font-weight: bold;flex-direction: unset;float: unset;height: auto;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 5px;overflow-x: unset;overflow-y: unset;padding-top: 3px;padding-bottom: 1px;padding-left: 10px;padding-right: 10px; text-align: left;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset; "><span leaf="">Dubbo:RPC的智慧</span></span><span style="display: none;"></span><span style=" border-bottom-color: rgb(239, 235, 233);align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: solid;border-top-width: 1px;border-bottom-width: 36px;border-left-width: 1px;border-right-width: 20px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: transparent;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;color: rgb(0, 0, 0);display: inline-block;font-size: 16px;font-weight: bold;flex-direction: unset;float: unset;height: auto;justify-content: unset;letter-spacing: 0px;line-height: 1.1em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px; text-align: left;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset; "></span></h2> <p data-tool="mdnice编辑器" style="color: rgb(0, 0, 0);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;text-indent: 0em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">说到Dubbo,它可是把Netty用得出神入化。虽然Dubbo支持多种通信框架,但Netty是它的默认选择,而且是最成熟的实现。</span></p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: block;"><span style="display: none;"></span><span style="font-size: 20px;color: rgb(0, 0, 0);line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: bold;display: block;"><span leaf="">多协议支持</span></span><span style="display: none;"></span></h3> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg axupzvuyfjydeegicmbjgcsrlqhlfivpiaxhiowogar3ktbib4apblgvwdcbwusecab0qus2w0hwhozmc3a48xxxbcmohigunpy 640?wx_fmt="svg&from=appmsg");""></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">class</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">NettyServer</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">doOpen</span></span><span style="line-height: 26px;"><span leaf="">()</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> bootstrap = </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> ServerBootstrap();</span><br><span leaf=""> </span><br><span leaf=""> bossGroup = </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> NioEventLoopGroup(</span><span style="color: #d19a66;line-height: 26px;"><span leaf="">1</span></span><span leaf="">);</span><br><span leaf=""> workerGroup = </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> NioEventLoopGroup(getUrl().getPositiveParameter(</span><br><span leaf=""> Constants.IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS));</span><br><span leaf=""> </span><br><span leaf=""> bootstrap.group(bossGroup, workerGroup)</span><br><span leaf=""> .channel(NioServerSocketChannel</span><span style="line-height: 26px;"><span leaf="">.</span><span style="color: #c678dd;line-height: 26px;"><span leaf="">class</span></span><span leaf="">)</span><br><span leaf=""> .</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">childHandler</span></span><span leaf="">(</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">ChannelInitializer</span></span><span leaf=""><</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">NioSocketChannel</span></span><span leaf="">>() </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Override</span></span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">protected</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">initChannel</span></span><span style="line-height: 26px;"><span leaf="">(NioSocketChannel ch)</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 这个Pipeline设计得很赞</span></span><br><span leaf=""> ChannelPipeline pipeline = ch.pipeline();</span><br><span leaf=""> pipeline.addLast(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"decoder"</span></span><span leaf="">, </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> DubboCodec());</span><br><span leaf=""> pipeline.addLast(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"handler"</span></span><span leaf="">, </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> HeaderExchangeHandler());</span><br><span leaf=""> }</span><br><span leaf=""> });</span><br><span leaf=""> }</span><br><span leaf="">}</span><br></code></pre> <p data-tool="mdnice编辑器" style="color: rgb(0, 0, 0);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;text-indent: 0em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">有趣的是Dubbo的编解码器设计:</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg axupzvuyfjydeegicmbjgcsrlqhlfivpiaxhiowogar3ktbib4apblgvwdcbwusecab0qus2w0hwhozmc3a48xxxbcmohigunpy 640?wx_fmt="svg&from=appmsg");""></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">class</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">DubboCodec</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">extends</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">ByteToMessageDecoder</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Override</span></span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">protected</span></span><span leaf=""> Object </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">decode</span></span><span style="line-height: 26px;"><span leaf="">(Channel channel, ByteBuf input)</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">byte</span></span><span leaf="">[] header = </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">byte</span></span><span leaf="">[</span><span style="color: #d19a66;line-height: 26px;"><span leaf="">16</span></span><span leaf="">];</span><br><span leaf=""> input.readBytes(header);</span><br><span leaf=""> </span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// Dubbo的魔数检查,这个设计我们可以学习</span></span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">if</span></span><span leaf=""> (header[</span><span style="color: #d19a66;line-height: 26px;"><span leaf="">0</span></span><span leaf="">] != MAGIC_HIGH || header[</span><span style="color: #d19a66;line-height: 26px;"><span leaf="">1</span></span><span leaf="">] != MAGIC_LOW) {</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">throw</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> IOException(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"Error magic number!"</span></span><span leaf="">);</span><br><span leaf=""> }</span><br><span leaf=""> </span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 解析协议版本、请求类型等</span></span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">return</span></span><span leaf=""> decodebody(...);</span><br><span leaf=""> }</span><br><span leaf="">}</span><br></code></pre> <h2 data-tool="mdnice编辑器" style=" border-bottom-color: rgb(239, 112, 96);margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 2px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: unset;line-height: 1.1em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;color: rgb(255, 255, 255);background-color: rgb(239, 112, 96);line-height: 1.5em;letter-spacing: 0em;align-items: unset;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 3px;border-top-right-radius: 3px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: inline-block;font-weight: bold;flex-direction: unset;float: unset;height: auto;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 5px;overflow-x: unset;overflow-y: unset;padding-top: 3px;padding-bottom: 1px;padding-left: 10px;padding-right: 10px; text-align: left;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset; "><span leaf="">Spring WebFlux:响应式的艺术</span></span><span style="display: none;"></span><span style=" border-bottom-color: rgb(239, 235, 233);align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: solid;border-top-width: 1px;border-bottom-width: 36px;border-left-width: 1px;border-right-width: 20px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: transparent;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;color: rgb(0, 0, 0);display: inline-block;font-size: 16px;font-weight: bold;flex-direction: unset;float: unset;height: auto;justify-content: unset;letter-spacing: 0px;line-height: 1.1em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px; text-align: left;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset; "></span></h2> <p data-tool="mdnice编辑器" style="color: rgb(0, 0, 0);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;text-indent: 0em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">WebFlux是Spring 5引入的响应式Web框架,它的底层网络也是用的Netty。说实话,它对Netty的使用特别优雅。</span></p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: block;"><span style="display: none;"></span><span style="font-size: 20px;color: rgb(0, 0, 0);line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: bold;display: block;"><span leaf="">响应式处理</span></span><span style="display: none;"></span></h3> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg axupzvuyfjydeegicmbjgcsrlqhlfivpiaxhiowogar3ktbib4apblgvwdcbwusecab0qus2w0hwhozmc3a48xxxbcmohigunpy 640?wx_fmt="svg&from=appmsg");""></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">class</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">HttpServerRoutes</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> RouterFunction <serverresponse> route = RouterFunctions </serverresponse></span><br><span leaf=""> .route(GET(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"/hello"</span></span><span leaf="">), </span><br><span leaf=""> request -> ServerResponse.ok()</span><br><span leaf=""> .body(Mono.just(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"Hello, Reactive!"</span></span><span leaf="">), String</span><span style="line-height: 26px;"><span leaf="">.</span><span style="color: #c678dd;line-height: 26px;"><span leaf="">class</span></span><span leaf="">))</span><br><span leaf=""> .</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">andRoute</span></span><span leaf="">(</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">POST</span></span><span leaf="">("/</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">upload</span></span><span leaf="">"), </span><br><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">request</span></span><span leaf=""> -> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">request</span></span><span leaf="">.</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">bodyToFlux</span></span><span leaf="">(</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">DataBuffer</span></span><span leaf="">.</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">class</span></span><span leaf="">)</span><br><span leaf=""> .</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">map</span></span><span leaf="">(</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">buffer</span></span><span leaf=""> -> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">handleBuffer</span></span><span leaf="">(</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">buffer</span></span><span leaf="">))</span><br><span leaf=""> .</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">then</span></span><span leaf="">(</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">ServerResponse</span></span><span leaf="">.</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">ok</span></span><span leaf="">().</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">build</span></span><span leaf="">()))</span></span><span leaf="">;</span><br><span leaf="">}</span><br></code></pre> <p data-tool="mdnice编辑器" style="color: rgb(0, 0, 0);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;text-indent: 0em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">WebFlux是怎么和Netty配合的?看这段代码:</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg axupzvuyfjydeegicmbjgcsrlqhlfivpiaxhiowogar3ktbib4apblgvwdcbwusecab0qus2w0hwhozmc3a48xxxbcmohigunpy 640?wx_fmt="svg&from=appmsg");""></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">class</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">ReactorHttpHandlerAdapter</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">extends</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">ChannelInboundHandlerAdapter</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Override</span></span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">channelRead</span></span><span style="line-height: 26px;"><span leaf="">(ChannelHandlerContext ctx, Object msg)</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">if</span></span><span leaf=""> (msg </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">instanceof</span></span><span leaf=""> HttpRequest) {</span><br><span leaf=""> HttpRequest request = (HttpRequest) msg;</span><br><span leaf=""> NettyServerHttpRequest adaptedRequest = </span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> NettyServerHttpRequest(ctx, request);</span><br><span leaf=""> </span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 转换成响应式流处理</span></span><br><span leaf=""> handle(adaptedRequest)</span><br><span leaf=""> .doOnSuccess(response -> </span><br><span leaf=""> response.writeWith(Flux.just(buffer))</span><br><span leaf=""> .subscribe())</span><br><span leaf=""> .subscribe();</span><br><span leaf=""> }</span><br><span leaf=""> }</span><br><span leaf="">}</span><br></code></pre> <p data-tool="mdnice编辑器" style="color: rgb(0, 0, 0);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;text-indent: 0em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">这里面有很多值得学习的设计:</span></p> <ol style="list-style-type: decimal;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">适配器模式的巧妙运用</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">响应式流与Netty的完美结合</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">非阻塞式的请求处理</span> </section></li> </ol> <h2 data-tool="mdnice编辑器" style=" border-bottom-color: rgb(239, 112, 96);margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 2px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: unset;line-height: 1.1em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;color: rgb(255, 255, 255);background-color: rgb(239, 112, 96);line-height: 1.5em;letter-spacing: 0em;align-items: unset;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 3px;border-top-right-radius: 3px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: inline-block;font-weight: bold;flex-direction: unset;float: unset;height: auto;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 5px;overflow-x: unset;overflow-y: unset;padding-top: 3px;padding-bottom: 1px;padding-left: 10px;padding-right: 10px; text-align: left;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset; "><span leaf="">Elasticsearch:搜索引擎的秘密</span></span><span style="display: none;"></span><span style=" border-bottom-color: rgb(239, 235, 233);align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: solid;border-top-width: 1px;border-bottom-width: 36px;border-left-width: 1px;border-right-width: 20px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: transparent;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;color: rgb(0, 0, 0);display: inline-block;font-size: 16px;font-weight: bold;flex-direction: unset;float: unset;height: auto;justify-content: unset;letter-spacing: 0px;line-height: 1.1em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px; text-align: left;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset; "></span></h2> <p data-tool="mdnice编辑器" style="color: rgb(0, 0, 0);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;text-indent: 0em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">ES的集群间通信也是用Netty实现的。它的实现特别有特色:</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg axupzvuyfjydeegicmbjgcsrlqhlfivpiaxhiowogar3ktbib4apblgvwdcbwusecab0qus2w0hwhozmc3a48xxxbcmohigunpy 640?wx_fmt="svg&from=appmsg");""></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">class</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">Netty4Transport</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">extends</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">TcpTransport</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">protected</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">doStart</span></span><span style="line-height: 26px;"><span leaf="">()</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> bootstrap = </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> ServerBootstrap();</span><br><span leaf=""> bootstrap.group(</span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> NioEventLoopGroup(settings.get(WORKER_COUNT)))</span><br><span leaf=""> .channel(NioServerSocketChannel</span><span style="line-height: 26px;"><span leaf="">.</span><span style="color: #c678dd;line-height: 26px;"><span leaf="">class</span></span><span leaf="">)</span><br><span leaf=""> .</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">childHandler</span></span><span leaf="">(</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">ChannelInitializer</span></span><span leaf=""><</span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">Channel</span></span><span leaf="">>() </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Override</span></span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">protected</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">initChannel</span></span><span style="line-height: 26px;"><span leaf="">(Channel ch)</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 看看这个Pipeline的设计</span></span><br><span leaf=""> ch.pipeline()</span><br><span leaf=""> .addLast(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"ssl"</span></span><span leaf="">, </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> SslHandler())</span><br><span leaf=""> .addLast(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"size"</span></span><span leaf="">, </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> MessageSizeHandler())</span><br><span leaf=""> .addLast(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"compress"</span></span><span leaf="">, </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> MessageCompressionHandler())</span><br><span leaf=""> .addLast(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"dispatcher"</span></span><span leaf="">, </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> MessageDispatcher());</span><br><span leaf=""> }</span><br><span leaf=""> });</span><br><span leaf=""> }</span><br><span leaf="">}</span><br></code></pre> <p data-tool="mdnice编辑器" style="color: rgb(0, 0, 0);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;text-indent: 0em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">ES的这套网络架构教会我们:</span></p> <ol style="list-style-type: decimal;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">安全性要放在第一位(SSL)</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">消息压缩很重要</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">分发机制要设计好</span> </section></li> </ol> <h2 data-tool="mdnice编辑器" style=" border-bottom-color: rgb(239, 112, 96);margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 2px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: unset;line-height: 1.1em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;color: rgb(255, 255, 255);background-color: rgb(239, 112, 96);line-height: 1.5em;letter-spacing: 0em;align-items: unset;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 3px;border-top-right-radius: 3px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: inline-block;font-weight: bold;flex-direction: unset;float: unset;height: auto;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 5px;overflow-x: unset;overflow-y: unset;padding-top: 3px;padding-bottom: 1px;padding-left: 10px;padding-right: 10px; text-align: left;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset; "><span leaf="">经验总结</span></span><span style="display: none;"></span><span style=" border-bottom-color: rgb(239, 235, 233);align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: solid;border-top-width: 1px;border-bottom-width: 36px;border-left-width: 1px;border-right-width: 20px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: transparent;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;color: rgb(0, 0, 0);display: inline-block;font-size: 16px;font-weight: bold;flex-direction: unset;float: unset;height: auto;justify-content: unset;letter-spacing: 0px;line-height: 1.1em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px; text-align: left;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset; "></span></h2> <p data-tool="mdnice编辑器" style="color: rgb(0, 0, 0);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;text-indent: 0em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">研究这些框架的源码,我学到了很多:</span></p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: block;"><span style="display: none;"></span><span style="font-size: 20px;color: rgb(0, 0, 0);line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: bold;display: block;"><span leaf="">1. 协议设计</span></span><span style="display: none;"></span></h3> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">使用魔数标识协议</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">预留版本号字段</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">支持协议扩展</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">考虑向后兼容</span> </section></li> </ul> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: block;"><span style="display: none;"></span><span style="font-size: 20px;color: rgb(0, 0, 0);line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: bold;display: block;"><span leaf="">2. 性能优化</span></span><span style="display: none;"></span></h3> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">池化技术的运用</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">零拷贝的使用</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">内存管理的重要性</span> </section></li> </ul> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: block;"><span style="display: none;"></span><span style="font-size: 20px;color: rgb(0, 0, 0);line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: bold;display: block;"><span leaf="">3. 可靠性保障</span></span><span style="display: none;"></span></h3> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">心跳机制的实现</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">优雅的重连策略</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">异常处理的完整性</span> </section></li> </ul> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: block;"><span style="display: none;"></span><span style="font-size: 20px;color: rgb(0, 0, 0);line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: bold;display: block;"><span leaf="">4. 代码设计</span></span><span style="display: none;"></span></h3> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">接口抽象要合理</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">组件职责要单一</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">扩展性要考虑周全</span> </section></li> </ul> <h2 data-tool="mdnice编辑器" style=" border-bottom-color: rgb(239, 112, 96);margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 2px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: unset;line-height: 1.1em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;color: rgb(255, 255, 255);background-color: rgb(239, 112, 96);line-height: 1.5em;letter-spacing: 0em;align-items: unset;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 3px;border-top-right-radius: 3px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: inline-block;font-weight: bold;flex-direction: unset;float: unset;height: auto;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 5px;overflow-x: unset;overflow-y: unset;padding-top: 3px;padding-bottom: 1px;padding-left: 10px;padding-right: 10px; text-align: left;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset; "><span leaf="">写在最后</span></span><span style="display: none;"></span><span style=" border-bottom-color: rgb(239, 235, 233);align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: solid;border-top-width: 1px;border-bottom-width: 36px;border-left-width: 1px;border-right-width: 20px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: transparent;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;color: rgb(0, 0, 0);display: inline-block;font-size: 16px;font-weight: bold;flex-direction: unset;float: unset;height: auto;justify-content: unset;letter-spacing: 0px;line-height: 1.1em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px; text-align: left;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset; "></span></h2> <p data-tool="mdnice编辑器" style="color: rgb(0, 0, 0);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;text-indent: 0em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">回顾这些框架对Netty的使用,能看出它们都有各自的特点:</span></p> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">RocketMQ注重性能和可靠性</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">Dubbo强调协议的扩展性</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">WebFlux追求响应式处理</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(1, 1, 1);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;font-weight: normal;"> <span leaf="">ES重视安全性和压缩处理</span> </section></li> </ul> <p data-tool="mdnice编辑器" style="color: rgb(0, 0, 0);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;text-indent: 0em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">这些设计思路都值得我们学习。说实话,看这些优秀的开源项目源码,就像在和高手过招,每次都能学到新东西。</span></p> <p data-tool="mdnice编辑器" style="color: rgb(0, 0, 0);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;text-indent: 0em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">你们在看这些框架源码时,有没有发现什么有趣的设计?欢迎在评论区分享你的发现!</span></p> <p data-tool="mdnice编辑器" style="color: rgb(0, 0, 0);font-size: 16px;line-height: 1.8em;letter-spacing: 0em;text-align: left;text-indent: 0em;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">至此,我们的Netty系列就告一段落了。回顾这些文章,我们从NIO聊到Netty,从原理聊到实践,从基础组件聊到开源框架,算是对Netty有了一个全面的认识。希望这些内容对大家有帮助!</span></p> </section>
作者:微信小助手
<p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(119, 119, 119);font-size: 14px;"><span leaf=""><span textstyle="" style="font-weight: bold;">记录20亿的用户连续 7 天的打卡数据,如何统计出这连续 7 天连续打卡用户总数呢?</span></span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">我们把每天的日期作为 Bitmap 的 key,userId 作为 offset,若是打卡则将 offset 位置的 bit 设置成 1。</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">key 对应的集合的每个 bit 位的数据则是一个用户在该日期的打卡记录。</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">一共有 7 个这样的 Bitmap,如果我们能对这 7 个 Bitmap 的对应的 bit 位做 『与』运算。</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">同样的 UserID offset 都是一样的,当一个 userID 在 7 个 Bitmap 对应对应的 offset 位置的 bit = 1 就说明该用户 7 天连续打卡。</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">结果保存到一个新 Bitmap 中,我们再通过</span></span><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(10, 191, 91);background-color: rgb(243, 245, 249);font-size: 14px;"><span leaf="">BITCOUNT</span></span></code><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">统计 bit = 1 的个数便得到了连续打卡 7 天的用户总数了。</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">Redis 提供了</span></span><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(10, 191, 91);background-color: rgb(243, 245, 249);font-size: 14px;"><span leaf="">BITOP operation destkey key [key ...]</span></span></code><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">这个指令用于对一个或者多个 键 = key 的 Bitmap 进行位元操作。</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(10, 191, 91);background-color: rgb(243, 245, 249);font-size: 14px;"><span leaf="">opration</span></span></code><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">可以是</span></span><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(10, 191, 91);background-color: rgb(243, 245, 249);font-size: 14px;"><span leaf="">and</span></span></code><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">、</span></span><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(10, 191, 91);background-color: rgb(243, 245, 249);font-size: 14px;"><span leaf="">OR</span></span></code><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">、</span></span><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(10, 191, 91);background-color: rgb(243, 245, 249);font-size: 14px;"><span leaf="">NOT</span></span></code><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">、</span></span><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(10, 191, 91);background-color: rgb(243, 245, 249);font-size: 14px;"><span leaf="">XOR</span></span></code><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">。当 BITOP 处理不同长度的字符串时,较短的那个字符串所缺少的部分会被看作</span></span><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(10, 191, 91);background-color: rgb(243, 245, 249);font-size: 14px;"><span leaf="">0</span></span></code><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">。空的</span></span><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(10, 191, 91);background-color: rgb(243, 245, 249);font-size: 14px;"><span leaf="">key</span></span></code><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">也被看作是包含</span></span><code style="font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;background-color: rgba(0, 0, 0, 0.06);border: 1px solid rgba(0, 0, 0, 0.08);border-radius: 2px;padding: 0px 2px;"><span style="color: rgb(10, 191, 91);background-color: rgb(243, 245, 249);font-size: 14px;"><span leaf="">0</span></span></code><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">的字符串序列。</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">便于理解,如下图所示:</span></span></p> <section style="text-align: center;" nodeleaf=""> <img src="/upload/b74ba622c44b63dc5ab2d535859e2abd.png" class="rich_pages wxw-img" data-ratio="0.362962962962963" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="100000621"> </section> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">3 个 Bitmap,对应的 bit 位做「与」操作,结果保存到新的 Bitmap 中。</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">操作指令表示将 三个 bitmap 进行 AND 操作,并将结果保存到 destmap 中。接着对 destmap 执行 BITCOUNT 统计。</span></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="javascript"><code><span leaf=""><span class="code-snippet__comment">// 与操作</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">BITOP AND destmap bitmap:01 bitmap:02 bitmap:03</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">// 统计 bit 位 = 1 的个数</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">BITCOUNT destmap</span></span></code></pre> </section><ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%22u559edf80%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u6d6bcd9a%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(51%2C%2051%2C%2051)%22%2C%22fontsize%22%3A14%7D%2C%22data%22%3A%22%E7%AE%80%E5%8D%95%E8%AE%A1%E7%AE%97%E4%B8%8B%20%E4%B8%80%E4%B8%AA%E4%B8%80%E4%BA%BF%E4%B8%AA%E4%BD%8D%E7%9A%84%20Bitmap%E5%8D%A0%E7%94%A8%E7%9A%84%E5%86%85%E5%AD%98%E5%BC%80%E9%94%80%EF%BC%8C%E5%A4%A7%E7%BA%A6%E5%8D%A0%2012%20MB%20%E7%9A%84%E5%86%85%E5%AD%98%EF%BC%8810%5E8%2F8%2F1024%2F1024%EF%BC%89%EF%BC%8C7%20%E5%A4%A9%E7%9A%84%20Bitmap%20%E7%9A%84%E5%86%85%E5%AD%98%E5%BC%80%E9%94%80%E7%BA%A6%E4%B8%BA%2084%20MB%E3%80%82%E5%90%8C%E6%97%B6%E6%88%91%E4%BB%AC%E6%9C%80%E5%A5%BD%E7%BB%99%20Bitmap%20%E8%AE%BE%E7%BD%AE%E8%BF%87%E6%9C%9F%E6%97%B6%E9%97%B4%EF%BC%8C%E8%AE%A9%20Redis%20%E5%88%A0%E9%99%A4%E8%BF%87%E6%9C%9F%E7%9A%84%E6%89%93%E5%8D%A1%E6%95%B0%E6%8D%AE%EF%BC%8C%E8%8A%82%E7%9C%81%E5%86%85%E5%AD%98%E3%80%82%22%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fypgse0xcb95ww30v"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">简单计算下 一个一亿个位的 Bitmap占用的内存开销,大约占 12 MB 的内存(10^8/8/1024/1024),7 天的 Bitmap 的内存开销约为 84 MB。同时我们最好给 Bitmap 设置过期时间,让 Redis 删除过期的打卡数据,节省内存。</span></span></p><ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%22ub9805d7d%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u8c693aa8%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(51%2C%2051%2C%2051)%22%2C%22fontsize%22%3A14%7D%2C%22data%22%3A%22%E7%A4%BA%E4%BE%8B%22%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fypgse0xcb95ww30v"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf=""><span textstyle="" style="font-weight: bold;">示例</span></span></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="bash"><code><span leaf=""><span class="code-snippet__comment"># 假设有3个用户(ID: 1001,1002,1003)在3天内的打卡记录 </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"># 第一天打卡记录 bitmap:20241213 </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">SETBIT bitmap:20241213 1001 1 # 用户1001打卡 </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">SETBIT bitmap:20241213 1002 1 # 用户1002打卡 </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">SETBIT bitmap:20241213 1003 0 # 用户1003未打卡 </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"># 第二天打卡记录 bitmap:20241214 </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">SETBIT bitmap:20241214 1001 1 # 用户1001打卡 </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">SETBIT bitmap:20241214 1002 0 # 用户1002未打卡 </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">SETBIT bitmap:20241214 1003 1 # 用户1003打卡 </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"># 第三天打卡记录 bitmap:20241215 </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">SETBIT bitmap:20241215 1001 1 # 用户1001打卡 </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">SETBIT bitmap:20241215 1002 1 # 用户1002打卡 </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">SETBIT bitmap:20241215 1003 1 # 用户1003打卡 </span></span></code></pre> </section><ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%22ue02c362a%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22ub8414eb0%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgba(6%2C%208%2C%2031%2C%200.88)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E7%8E%B0%E5%9C%A8%E5%88%86%E6%9E%90%E6%AF%8F%E4%B8%AA%E7%94%A8%E6%88%B7%E7%9A%84%E6%83%85%E5%86%B5%EF%BC%9A%22%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fypgse0xcb95ww30v"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgba(6, 8, 31, 0.88);font-size: 16px;"><span leaf="">现在分析每个用户的情况:</span></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang=""><code><span leaf=""><span class="code-snippet__plaintext">用户1001的打卡记录:1 1 1 (连续打卡) </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">用户1002的打卡记录:1 0 1 (没有连续打卡) </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">用户1003的打卡记录:0 1 1 (没有连续打卡)</span></span></code></pre> </section><ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%22u213074f7%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22ube21c1f1%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgba(6%2C%208%2C%2031%2C%200.88)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E6%89%A7%E8%A1%8CBITOP%20AND%E6%93%8D%E4%BD%9C%EF%BC%9A%22%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fypgse0xcb95ww30v"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgba(6, 8, 31, 0.88);font-size: 16px;"><span leaf="">执行BITOP AND操作:</span></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="bash"><code><span leaf=""><span class="code-snippet__comment"># 对三天的bitmap进行与运算,结果存入destmap </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">BITOP AND destmap bitmap:20241213 bitmap:20241214 bitmap:20241215 </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext"># 结果分析: </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">用户1001: 1 AND 1 AND 1 = 1 (在destmap中是1) </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">用户1002: 1 AND 0 AND 1 = 0 (在destmap中是0) </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">用户1003: 0 AND 1 AND 1 = 0 (在destmap中是0)</span></span></code></pre> </section><ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%22u884f24d3%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u1ff7a0dd%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgba(6%2C%208%2C%2031%2C%200.88)%22%2C%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E7%BB%9F%E8%AE%A1%E8%BF%9E%E7%BB%AD%E6%89%93%E5%8D%A1%E7%94%A8%E6%88%B7%E6%95%B0%EF%BC%9A%22%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fypgse0xcb95ww30v"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgba(6, 8, 31, 0.88);font-size: 16px;"><span leaf="">统计连续打卡用户数:</span></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="bash"><code><span leaf=""><span class="code-snippet__comment"># 统计destmap中1的个数 </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">BITCOUNT destmap # 结果为1,表示只有用户1001连续打卡</span></span></code></pre> </section> <section style="text-align: center;" nodeleaf=""> <img src="/upload/c6b9812ee5b2f56923e988d6db62ba38.png" class="rich_pages wxw-img" data-ratio="0.5685185185185185" data-s="300,640" data-type="png" data-w="1080" type="block" data-imgfileid="100000622"> </section><ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%22ubc538e0e%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22uf9520d78%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22fontsize%22%3A16%7D%2C%22data%22%3A%22%E5%88%86%E6%9E%90%22%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fypgse0xcb95ww30v"></ne-clipboard> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="font-size: 16px;"><span leaf=""><span textstyle="" style="font-weight: bold;">分析</span></span></span></p> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="sql"><code><span leaf=""><span class="code-snippet__plaintext">三天的打卡记录可以表示为: </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__keyword">offset</span><span class="code-snippet__plaintext">(用户ID): </span><span class="code-snippet__number">1001</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">1002</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">1003</span><span class="code-snippet__plaintext"> </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">第一天: </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> (bitmap:</span><span class="code-snippet__number">20241213</span><span class="code-snippet__plaintext">) </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">第二天: </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext"> (bitmap:</span><span class="code-snippet__number">20241214</span><span class="code-snippet__plaintext">) </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">第三天: </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext"> (bitmap:</span><span class="code-snippet__number">20241215</span><span class="code-snippet__plaintext">) </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">执行BITOP </span><span class="code-snippet__keyword">AND</span><span class="code-snippet__plaintext">操作: </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">BITOP </span><span class="code-snippet__keyword">AND</span><span class="code-snippet__plaintext"> destmap bitmap:</span><span class="code-snippet__number">20241213</span><span class="code-snippet__plaintext"> bitmap:</span><span class="code-snippet__number">20241214</span><span class="code-snippet__plaintext"> bitmap:</span><span class="code-snippet__number">20241215</span><span class="code-snippet__plaintext"> </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">计算过程: </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">用户</span><span class="code-snippet__number">1001</span><span class="code-snippet__plaintext">的位置: </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">AND</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">AND</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">=</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext"> (三天都打卡) </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">用户</span><span class="code-snippet__number">1002</span><span class="code-snippet__plaintext">的位置: </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">AND</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">AND</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">=</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> (第二天没打卡) </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">用户</span><span class="code-snippet__number">1003</span><span class="code-snippet__plaintext">的位置: </span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">AND</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">AND</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__operator">=</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> (第一天没打卡) </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">最终destmap的结果: </span></span></code><code><span leaf=""><span class="code-snippet__keyword">offset</span><span class="code-snippet__plaintext">(用户ID): </span><span class="code-snippet__number">1001</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">1002</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">1003</span><span class="code-snippet__plaintext"> </span></span></code><code><span leaf=""><span class="code-snippet__plaintext">destmap: </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> </span></span></code><code><span leaf=""><br></span></code><code><span leaf=""><span class="code-snippet__plaintext">当执行 BITCOUNT destmap 时: </span></span></code><code><span leaf=""><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> 统计destmap中值为</span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext">的位数 </span></span></code><code><span leaf=""><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> 只有</span><span class="code-snippet__number">1001</span><span class="code-snippet__plaintext">这个位置是</span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext"> </span></span></code><code><span leaf=""><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> 其他位置都是</span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext"> </span></span></code><code><span leaf=""><span class="code-snippet__operator">-</span><span class="code-snippet__plaintext"> 所以结果为</span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext">,表示只有一个用户完成连续打卡 </span></span></code></pre> </section> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="font-size: 16px;"><span leaf=""><br></span></span></p><ne-clipboard data="%7B%22type%22%3A%22fragment%22%2C%22name%22%3A%22%23fragment%22%2C%22children%22%3A%5B%7B%22type%22%3A%22element%22%2C%22id%22%3A%228rl96%22%2C%22name%22%3A%22h3%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22ua8124606%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22bold%22%3Atrue%2C%22color%22%3A%22rgb(0%2C%200%2C%200)%22%7D%2C%22data%22%3A%22%E5%B0%8F%E7%BB%93%22%7D%5D%7D%2C%7B%22type%22%3A%22element%22%2C%22id%22%3A%22uf74cc7ae%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22ubc84b7f8%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(51%2C%2051%2C%2051)%22%2C%22fontsize%22%3A14%7D%2C%22data%22%3A%22%E6%80%9D%E8%B7%AF%E6%89%8D%E6%98%AF%E6%9C%80%E9%87%8D%E8%A6%81%EF%BC%8C%E5%BD%93%E6%88%91%E4%BB%AC%E9%81%87%E5%88%B0%E7%9A%84%E7%BB%9F%E8%AE%A1%E5%9C%BA%E6%99%AF%E5%8F%AA%E9%9C%80%E8%A6%81%E7%BB%9F%E8%AE%A1%E6%95%B0%E6%8D%AE%E7%9A%84%E4%BA%8C%E5%80%BC%E7%8A%B6%E6%80%81%EF%BC%8C%E6%AF%94%E5%A6%82%E7%94%A8%E6%88%B7%E6%98%AF%E5%90%A6%E5%AD%98%E5%9C%A8%E3%80%81%20ip%20%E6%98%AF%E5%90%A6%E6%98%AF%E9%BB%91%E5%90%8D%E5%8D%95%E3%80%81%E4%BB%A5%E5%8F%8A%E7%AD%BE%E5%88%B0%E6%89%93%E5%8D%A1%E7%BB%9F%E8%AE%A1%E7%AD%89%E5%9C%BA%E6%99%AF%E5%B0%B1%E5%8F%AF%E4%BB%A5%E8%80%83%E8%99%91%E4%BD%BF%E7%94%A8%20Bitmap%E3%80%82%22%7D%5D%7D%2C%7B%22type%22%3A%22element%22%2C%22id%22%3A%22u18b0a1cf%22%2C%22name%22%3A%22p%22%2C%22attrs%22%3A%7B%7D%2C%22children%22%3A%5B%7B%22type%22%3A%22text%22%2C%22id%22%3A%22u7c06cd83%22%2C%22name%22%3A%22%23text%22%2C%22attrs%22%3A%7B%22color%22%3A%22rgb(51%2C%2051%2C%2051)%22%2C%22fontsize%22%3A14%7D%2C%22data%22%3A%22%E5%8F%AA%E9%9C%80%E8%A6%81%E4%B8%80%E4%B8%AA%20bit%20%E4%BD%8D%E5%B0%B1%E8%83%BD%E8%A1%A8%E7%A4%BA%200%20%E5%92%8C%201%E3%80%82%E5%9C%A8%E7%BB%9F%E8%AE%A1%E6%B5%B7%E9%87%8F%E6%95%B0%E6%8D%AE%E7%9A%84%E6%97%B6%E5%80%99%E5%B0%86%E5%A4%A7%E5%A4%A7%E5%87%8F%E5%B0%91%E5%86%85%E5%AD%98%E5%8D%A0%E7%94%A8%E3%80%82%22%7D%5D%7D%5D%2C%22attrs%22%3A%7B%7D%7D" source="https%3A%2F%2Fwww.yuque.com%2Fu12222632%2Fas5rgl%2Fypgse0xcb95ww30v"></ne-clipboard> <h3 style="font-size: 20;line-height: 28px;margin: 16px 0 5px 0;"><strong><span style="color: rgb(0, 0, 0);"><span leaf="">总结</span></span></strong></h3> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">当我们遇到的统计场景只需要统计数据的二值状态,比如用户是否存在、 ip 是否是黑名单、以及签到打卡统计等场景就可以考虑使用 Bitmap。</span></span></p> <p style="margin: 0;padding: 0;min-height: 24px;"><span style="color: rgb(51, 51, 51);font-size: 14px;"><span leaf="">只需要一个 bit 位就能表示 0 和 1。在统计海量数据的时候将大大减少内存占用。</span></span></p>
作者:微信小助手
<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="margin-bottom: 0px;padding-left: 10px;padding-right: 10px;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;width: auto;font-family: Optima, " microsoft yahei, pingfangsc-regular, serif;font-size: 16px;color: rgb(0, 0, 0);line-height: 1.5em;word-spacing: 0em;letter-spacing: 0em;word-break: break-word;text-align: left; data-mpa-powered-by="yiban.io"> <h1 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;background-attachment: scroll;background-clip: border-box;background-image: url(" https: mmbiz.qpic.cn mmbiz_jpg pmzoeonjxwc5p16tqysanspnkbrxfxxfqzjf2xcbjibnwrswd6iciajlnr8lhjoqg8nhwqaido8ow6kizvibyvc0yq 640?wx_fmt="other&from=appmsg");background-origin:" padding-box;background-position: 50% 50%;background-repeat: no-repeat;background-size: 75px;width: auto;height: auto;align-items: unset;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;justify-content: center;line-height: 1.5em;overflow: unset;text-shadow: none;transform: none;-webkit-box-reflect: unset;><span style="display: none;"></span><span style="font-size: 18px;color: rgb(72, 179, 120);line-height: 2.4em;letter-spacing: 0em;margin-top: 38px;margin-bottom: 10px;border-style: none none solid;border-width: 1px 1px 2px;border-color: rgb(0, 0, 0) rgb(0, 0, 0) rgb(46, 121, 80);border-radius: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;box-shadow: none;display: inline-block;font-weight: bold;flex-direction: unset;float: unset;height: 38px;justify-content: unset;overflow: unset;text-align: center;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset;">引言</span><span style="display: none;"></span></h1> <p data-tool="mdnice编辑器" style="color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;">大家好,我是老三,最近在做系统设计的时候,发现要画不少时序图,以前我用的最顺手的工具是draw.io,后来也尝试了语雀自带的画图工具,感觉画画简单的图还行,但是复杂一点的,就比较吃力了。<img class="rich_pages wxw-img" data-imgfileid="100012106" data-ratio="0.6231481481481481" src="/upload/ff87ceb3bf3373e7ba337ad3765e0f47.png" data-type="png" data-w="1080" style="display: block;margin-right: auto;margin-left: auto;">哎,这条线怎么又歪了?布局怎么又乱了?这个条怎么又对不齐了?……手忙脚乱才画好一张图,这时候我就想,有没有其它更专业的画图工具呢?大部分同事都在用Visio,辉哥给我推荐了PlantUML,说非常好用!这时候旁边来了一句—— “他就是装比!”</p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012105" data-ratio="0.6866666666666666" src="/upload/1c076c802a01ffdf3089355bc706ccb4.png" data-type="gif" data-w="150" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> 装比带我一个 </figcaption> </figure> <p data-tool="mdnice编辑器" style="color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;"><span style="color: rgb(63, 63, 63);font-family: Optima, " microsoft yahei, pingfangsc-regular, serif;font-size: 16px;letter-spacing: 0.32px;text-align: left;text-wrap: wrap;> 还有这样的事?</span><span style="color: rgb(63, 63, 63);font-family: Optima, " microsoft yahei, pingfangsc-regular, serif;font-size: 16px;letter-spacing: 0.32px;text-align: left;text-wrap: wrap;>那我不能让他一个人都装了。</span></p> <p data-tool="mdnice编辑器" style="color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;">最开始看下官方文档,发现PlantUML类似MarkDown,似乎需要一点学习成本,简单用了一下,曲线还是挺平缓的,上手相当快!推荐大家也用一下试试。</p> <h1 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;background-attachment: scroll;background-clip: border-box;background-image: url(" https: mmbiz.qpic.cn mmbiz_jpg pmzoeonjxwc5p16tqysanspnkbrxfxxfqzjf2xcbjibnwrswd6iciajlnr8lhjoqg8nhwqaido8ow6kizvibyvc0yq 640?wx_fmt="other&from=appmsg");background-origin:" padding-box;background-position: 50% 50%;background-repeat: no-repeat;background-size: 75px;width: auto;height: auto;align-items: unset;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;justify-content: center;line-height: 1.5em;overflow: unset;text-shadow: none;transform: none;-webkit-box-reflect: unset;><span style="display: none;"></span><span style="font-size: 18px;color: rgb(72, 179, 120);line-height: 2.4em;letter-spacing: 0em;margin-top: 38px;margin-bottom: 10px;border-style: none none solid;border-width: 1px 1px 2px;border-color: rgb(0, 0, 0) rgb(0, 0, 0) rgb(46, 121, 80);border-radius: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;box-shadow: none;display: inline-block;font-weight: bold;flex-direction: unset;float: unset;height: 38px;justify-content: unset;overflow: unset;text-align: center;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset;">一、什么是PlantUML?</span><span style="display: none;"></span></h1> <blockquote data-tool="mdnice编辑器" style="margin-top: 20px;margin-bottom: 20px;padding: 10px 10px 10px 20px;border-top: 3px none rgba(0, 0, 0, 0.4);border-bottom: 3px none rgba(0, 0, 0, 0.4);border-right: 3px none rgba(0, 0, 0, 0.4);border-left-color: rgb(53, 179, 120);border-radius: 0px;background: none 0% 0% / auto no-repeat scroll padding-box border-box rgb(251, 249, 253);width: auto;height: auto;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;overflow: auto;"> <span style="display: none;color: rgb(0, 0, 0);font-size: 16px;line-height: 1.5em;letter-spacing: 0em;"></span> <p style="text-indent: 0em;padding-top: 16px;padding-bottom: 8px;color: rgb(63, 63, 63);font-size: 16px;line-height: 1.8em;letter-spacing: 0.02em;"><strong style="color: rgb(74, 74, 74);background: none 0% 0% / auto no-repeat scroll padding-box border-box rgba(0, 0, 0, 0);width: auto;height: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 0px;">PlantUML</strong>是一个多功能组件,可快速、直接地创建图表。用户可以使用简单直观的语言起草各种图表。</p> </blockquote> <p data-tool="mdnice编辑器" style="color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;">PlantUML是一个开源工具,它允许我们用简单的文本描述来创建UML图,包括序列图、用例图、类图、对象图、活动图、组件图、部署图、状态图,以及我们今天要讲的时序图。<img class="rich_pages wxw-img" data-imgfileid="100012104" data-ratio="0.4715909090909091" src="/upload/309b78c467ee86c76f8c221c9c90d7d7.png" data-type="png" data-w="1056" style="display: block;margin-right: auto;margin-left: auto;">除了UML图之外,PlantUML 还支持一系列其他图表,例如JSON数据、YAML数据、EBNF图表、架构图等等。PlantUML的一大优势,是图表完全用文本代码描述,这就意味着它可以作为文档嵌入到源代码中,也非常方便版本控制和多人协作,不管是迭代设计、文档编写、系统建模,PlantUML都能胜任。</p> <h1 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;background-attachment: scroll;background-clip: border-box;background-image: url(" https: mmbiz.qpic.cn mmbiz_jpg pmzoeonjxwc5p16tqysanspnkbrxfxxfqzjf2xcbjibnwrswd6iciajlnr8lhjoqg8nhwqaido8ow6kizvibyvc0yq 640?wx_fmt="other&from=appmsg");background-origin:" padding-box;background-position: 50% 50%;background-repeat: no-repeat;background-size: 75px;width: auto;height: auto;align-items: unset;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;justify-content: center;line-height: 1.5em;overflow: unset;text-shadow: none;transform: none;-webkit-box-reflect: unset;><span style="display: none;"></span><span style="font-size: 18px;color: rgb(72, 179, 120);line-height: 2.4em;letter-spacing: 0em;margin-top: 38px;margin-bottom: 10px;border-style: none none solid;border-width: 1px 1px 2px;border-color: rgb(0, 0, 0) rgb(0, 0, 0) rgb(46, 121, 80);border-radius: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;box-shadow: none;display: inline-block;font-weight: bold;flex-direction: unset;float: unset;height: 38px;justify-content: unset;overflow: unset;text-align: center;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset;">二、快速入门</span><span style="display: none;"></span></h1> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;background-attachment: scroll;background-clip: border-box;background-image: url(" https: mmbiz.qpic.cn mmbiz_png pmzoeonjxwc5p16tqysanspnkbrxfxxfh0iaicjh4eraszazhu0qdcliaibiaib5o7rqxib2tnmlej1x74xjyyonrdk9a 640?wx_fmt="png&from=appmsg");background-origin:" padding-box;background-position: 50% 50%;background-repeat: no-repeat;background-size: 63px;width: auto;height: auto;align-items: unset;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;justify-content: center;line-height: 1.5em;overflow: unset;text-shadow: none;transform: none;-webkit-box-reflect: unset;><span style="display: none;"></span><span style="font-size: 18px;color: rgb(72, 179, 120);line-height: 2.4em;letter-spacing: 0em;margin-top: 38px;margin-bottom: 10px;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;box-shadow: none;display: inline-block;font-weight: bold;flex-direction: unset;float: unset;height: 38px;justify-content: unset;overflow: unset;text-align: center;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset;">PlantUML插件</span><span style="display: none;"></span></h2> <p data-tool="mdnice编辑器" style="color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;">为了便捷地使用PlantUML,许多流行的IDE和代码编辑器提供了集成PlantUML的插件,如Visual Studio Code、IntelliJ IDEA、Eclipse等。插件提供了实时预览、语法高亮和图表导出等功能,能帮助我们更快捷,更高效地画图,整体上IDEA的插件用起来体验最好,但是IDEA大家懂的,太占内存了,VS Code相对而言,用起来就会轻量很多。</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> <p style="line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;">IntelliJ IDEA:比如 "PlantUML integration" 可以让我们直接在 IDE 中查看和编辑 PlantUML 图表</p> <figure style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012107" data-ratio="0.737037037037037" src="/upload/f67cb608f92c4530eaf5d8c179c4cb7b.png" data-type="png" data-w="1080" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> PlantUML integration </figcaption> </figure> </section></li> <ul style="list-style-type: square;margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> 插件使用效果 </section></li> </ul> </ul> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012108" data-ratio="0.46111111111111114" src="/upload/3d9f16dac8931a7db574014f7633f677.png" data-type="png" data-w="1080" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> image.png </figcaption> </figure> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> VS Code:https://marketplace.visualstudio.com/items?itemName=jebbs.plantuml </section></li> <ul style="list-style-type: square;margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> 插件市场: </section></li> </ul> </ul> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012112" data-ratio="0.6981481481481482" src="/upload/3f000d36c8b05d5e9f4591c8a8561329.png" data-type="png" data-w="1080" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> image.png </figcaption> </figure> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> 插件使用效果: </section></li> </ul> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012113" data-ratio="0.5537037037037037" src="/upload/2dac24f33630e93aa83ff4ac2e0121de.png" data-type="png" data-w="1080" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> image.png </figcaption> </figure> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;background-attachment: scroll;background-clip: border-box;background-image: url(" https: mmbiz.qpic.cn mmbiz_png pmzoeonjxwc5p16tqysanspnkbrxfxxfh0iaicjh4eraszazhu0qdcliaibiaib5o7rqxib2tnmlej1x74xjyyonrdk9a 640?wx_fmt="png&from=appmsg");background-origin:" padding-box;background-position: 50% 50%;background-repeat: no-repeat;background-size: 63px;width: auto;height: auto;align-items: unset;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;justify-content: center;line-height: 1.5em;overflow: unset;text-shadow: none;transform: none;-webkit-box-reflect: unset;><span style="display: none;"></span><span style="font-size: 18px;color: rgb(72, 179, 120);line-height: 2.4em;letter-spacing: 0em;margin-top: 38px;margin-bottom: 10px;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;box-shadow: none;display: inline-block;font-weight: bold;flex-direction: unset;float: unset;height: 38px;justify-content: unset;overflow: unset;text-align: center;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset;">Hello World!</span><span style="display: none;"></span></h2> <p data-tool="mdnice编辑器" style="color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;">我们先来看个最简单的例子,通过<code style="color: rgb(40, 202, 113);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background: none 0% 0% / auto no-repeat scroll padding-box border-box rgba(27, 31, 35, 0.05);width: auto;height: auto;margin-left: 2px;margin-right: 2px;padding: 2px 4px;border-style: none;border-width: 3px;border-color: rgb(0, 0, 0) rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4);border-radius: 4px;font-family: " operator mono, consolas, monaco, menlo, monospace;word-break: break-all;>-></code> 、<code style="color: rgb(40, 202, 113);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background: none 0% 0% / auto no-repeat scroll padding-box border-box rgba(27, 31, 35, 0.05);width: auto;height: auto;margin-left: 2px;margin-right: 2px;padding: 2px 4px;border-style: none;border-width: 3px;border-color: rgb(0, 0, 0) rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4);border-radius: 4px;font-family: " operator mono, consolas, monaco, menlo, monospace;word-break: break-all;>--></code>和<code style="color: rgb(40, 202, 113);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background: none 0% 0% / auto no-repeat scroll padding-box border-box rgba(27, 31, 35, 0.05);width: auto;height: auto;margin-left: 2px;margin-right: 2px;padding: 2px 4px;border-style: none;border-width: 3px;border-color: rgb(0, 0, 0) rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4);border-radius: 4px;font-family: " operator mono, consolas, monaco, menlo, monospace;word-break: break-all;> :</code>就可以在参与者之间传递消息,不用明确声明参与者。</p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;margin-top: 10px;margin-bottom: 10px;"><span style="display: block;background: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbskyvchl3yzerhnm8cv0eribia6kxszvzrfthxrcn46sxzylwhefibb5fp8bicgummdghws2e8cur8qzy02zdldnaria 640?wx_fmt="svg&from=appmsg")" 10px 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;font-size: 12px;"><span style="color: #61aeee;line-height: 26px;">@startuml</span><br>老张 -> 老王 : 老王,你好啊<br>老王--> 老张: 老张,你好啊<br><br>老张 -> 老王: 最近有空一起喝茶<br>老张 <-- 老王: OK<br><span style="color: #61aeee;line-height: 26px;">@enduml</span><br></code></pre> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012109" data-ratio="1.2377777777777779" src="/upload/7031b84b4b941faf897916f4384d5b98.png" data-type="png" data-w="450" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> hello </figcaption> </figure> <h1 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;background-attachment: scroll;background-clip: border-box;background-image: url(" https: mmbiz.qpic.cn mmbiz_jpg pmzoeonjxwc5p16tqysanspnkbrxfxxfqzjf2xcbjibnwrswd6iciajlnr8lhjoqg8nhwqaido8ow6kizvibyvc0yq 640?wx_fmt="other&from=appmsg");background-origin:" padding-box;background-position: 50% 50%;background-repeat: no-repeat;background-size: 75px;width: auto;height: auto;align-items: unset;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;justify-content: center;line-height: 1.5em;overflow: unset;text-shadow: none;transform: none;-webkit-box-reflect: unset;><span style="display: none;"></span><span style="font-size: 18px;color: rgb(72, 179, 120);line-height: 2.4em;letter-spacing: 0em;margin-top: 38px;margin-bottom: 10px;border-style: none none solid;border-width: 1px 1px 2px;border-color: rgb(0, 0, 0) rgb(0, 0, 0) rgb(46, 121, 80);border-radius: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;box-shadow: none;display: inline-block;font-weight: bold;flex-direction: unset;float: unset;height: 38px;justify-content: unset;overflow: unset;text-align: center;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset;">三、PlantUML时序图语法</span><span style="display: none;"></span></h1> <p data-tool="mdnice编辑器" style="color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;">接下来,我们看看PlantUML时序图的一些具体语法。</p> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;background-attachment: scroll;background-clip: border-box;background-image: url(" https: mmbiz.qpic.cn mmbiz_png pmzoeonjxwc5p16tqysanspnkbrxfxxfh0iaicjh4eraszazhu0qdcliaibiaib5o7rqxib2tnmlej1x74xjyyonrdk9a 640?wx_fmt="png&from=appmsg");background-origin:" padding-box;background-position: 50% 50%;background-repeat: no-repeat;background-size: 63px;width: auto;height: auto;align-items: unset;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;justify-content: center;line-height: 1.5em;overflow: unset;text-shadow: none;transform: none;-webkit-box-reflect: unset;><span style="display: none;"></span><span style="font-size: 18px;color: rgb(72, 179, 120);line-height: 2.4em;letter-spacing: 0em;margin-top: 38px;margin-bottom: 10px;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;box-shadow: none;display: inline-block;font-weight: bold;flex-direction: unset;float: unset;height: 38px;justify-content: unset;overflow: unset;text-align: center;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset;">声明参与者</span><span style="display: none;"></span></h2> <p data-tool="mdnice编辑器" style="color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;">我们使用关键字participant 来声明参与者,就可以对该参与者进行更多的控制。声明的顺序就是默认的<strong style="color: rgb(74, 74, 74);background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 0px;">显示顺序</strong>。我们也可以用这些关键字来声明参与者,给参与者设置不同的形状。</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> actor(角色) </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> boundary(边界) </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> control(控制) </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> entity(实体) </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> database(数据库) </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> collections(集合) </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> queue(队列) </section></li> </ul> <p data-tool="mdnice编辑器" style="color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;">我们还可以通过 <code style="color: rgb(40, 202, 113);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background: none 0% 0% / auto no-repeat scroll padding-box border-box rgba(27, 31, 35, 0.05);width: auto;height: auto;margin-left: 2px;margin-right: 2px;padding: 2px 4px;border-style: none;border-width: 3px;border-color: rgb(0, 0, 0) rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4);border-radius: 4px;font-family: " operator mono, consolas, monaco, menlo, monospace;word-break: break-all;>as</code>关键字重命名参与者。</p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;margin-top: 10px;margin-bottom: 10px;"><span style="display: block;background: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbskyvchl3yzerhnm8cv0eribia6kxszvzrfthxrcn46sxzylwhefibb5fp8bicgummdghws2e8cur8qzy02zdldnaria 640?wx_fmt="svg&from=appmsg")" 10px 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;font-size: 12px;"><span style="color: #61aeee;line-height: 26px;">@startuml</span><br>participant Participant as Foo<br>actor Actor as Foo1<br>boundary Boundary as Foo2<br>control Control as Foo3<br>entity Entity as Foo4<br>database Database as Foo5<br>collections Collections as Foo6<br>queue Queue as Foo7<br><span style="color: #61aeee;line-height: 26px;">@enduml</span><br></code></pre> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012110" data-ratio="0.3225419664268585" src="/upload/297e0600ba7b1b74df24823626fc935d.png" data-type="png" data-w="834" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> 参与者 </figcaption> </figure> <p data-tool="mdnice编辑器" style="color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;">默认的颜色比较单调,也可以通过<code style="color: rgb(40, 202, 113);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background: none 0% 0% / auto no-repeat scroll padding-box border-box rgba(27, 31, 35, 0.05);width: auto;height: auto;margin-left: 2px;margin-right: 2px;padding: 2px 4px;border-style: none;border-width: 3px;border-color: rgb(0, 0, 0) rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4);border-radius: 4px;font-family: " operator mono, consolas, monaco, menlo, monospace;word-break: break-all;>#</code>来设置参与者的颜色:</p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;margin-top: 10px;margin-bottom: 10px;"><span style="display: block;background: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbskyvchl3yzerhnm8cv0eribia6kxszvzrfthxrcn46sxzylwhefibb5fp8bicgummdghws2e8cur8qzy02zdldnaria 640?wx_fmt="svg&from=appmsg")" 10px 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;font-size: 12px;"><span style="color: #61aeee;line-height: 26px;">@startuml</span><br>actor Bob #blue<br><span style="color: #98c379;line-height: 26px;">' The only difference between actor<br>'</span>and participant is the drawing<br>participant Alice #SkyBlue<br>participant <span style="color: #98c379;line-height: 26px;">"I have a really\nlong name"</span> as L #<span style="color: #d19a66;line-height: 26px;">00f</span>f00<br><br>Alice->Bob: Authentication Request<br>Bob->Alice: Authentication Response<br>Bob->L: Log transaction<br><span style="color: #61aeee;line-height: 26px;">@enduml</span><br></code></pre> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012111" data-ratio="0.8607038123167156" src="/upload/cb3fe7d790dda89c1766c13868b3659d.png" data-type="png" data-w="682" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> 上颜色的参与者 </figcaption> </figure> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;background-attachment: scroll;background-clip: border-box;background-image: url(" https: mmbiz.qpic.cn mmbiz_png pmzoeonjxwc5p16tqysanspnkbrxfxxfh0iaicjh4eraszazhu0qdcliaibiaib5o7rqxib2tnmlej1x74xjyyonrdk9a 640?wx_fmt="png&from=appmsg");background-origin:" padding-box;background-position: 50% 50%;background-repeat: no-repeat;background-size: 63px;width: auto;height: auto;align-items: unset;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;justify-content: center;line-height: 1.5em;overflow: unset;text-shadow: none;transform: none;-webkit-box-reflect: unset;><span style="display: none;"></span><span style="font-size: 18px;color: rgb(72, 179, 120);line-height: 2.4em;letter-spacing: 0em;margin-top: 38px;margin-bottom: 10px;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;box-shadow: none;display: inline-block;font-weight: bold;flex-direction: unset;float: unset;height: 38px;justify-content: unset;overflow: unset;text-align: center;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset;">消息传递</span><span style="display: none;"></span></h2> <p data-tool="mdnice编辑器" style="color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;">在不同参与者之间,通过箭头+:来表示消息传递。</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> 同步消息: </section></li> </ul> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;margin-top: 10px;margin-bottom: 10px;"><span style="display: block;background: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbskyvchl3yzerhnm8cv0eribia6kxszvzrfthxrcn46sxzylwhefibb5fp8bicgummdghws2e8cur8qzy02zdldnaria 640?wx_fmt="svg&from=appmsg")" 10px 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;font-size: 12px;">A -> B: 同步消息文本<br></code></pre> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012115" data-ratio="0.9397163120567376" src="/upload/f25483af4ba1f4673aa1771832b96c0f.png" data-type="png" data-w="282" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> 同步消息 </figcaption> </figure> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> 异步消息:由发送者A指向接收者B,表示A发送后不需要等待B立即处理。 </section></li> </ul> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;margin-top: 10px;margin-bottom: 10px;"><span style="display: block;background: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbskyvchl3yzerhnm8cv0eribia6kxszvzrfthxrcn46sxzylwhefibb5fp8bicgummdghws2e8cur8qzy02zdldnaria 640?wx_fmt="svg&from=appmsg")" 10px 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;font-size: 12px;">A ->> B: 异步消息文本<br></code></pre> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012118" data-ratio="0.9408284023668639" src="/upload/a3b74cf0c49f24f66935f368cddf1bc3.png" data-type="png" data-w="338" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> 异步消息 </figcaption> </figure> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> 返回消息:通常从接收者返回到发送者,标识一个回应。 </section></li> </ul> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;margin-top: 10px;margin-bottom: 10px;"><span style="display: block;background: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbskyvchl3yzerhnm8cv0eribia6kxszvzrfthxrcn46sxzylwhefibb5fp8bicgummdghws2e8cur8qzy02zdldnaria 640?wx_fmt="svg&from=appmsg")" 10px 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;font-size: 12px;">A <-- B: 返回消息文本<br><br></code></pre> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012114" data-ratio="0.9408284023668639" src="/upload/fdacd8718cd74973b92c5d215b6eb540.png" data-type="png" data-w="338" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> 返回消息 </figcaption> </figure> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> <p style="line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;">自调用:一个参与者直接发送消息给自己,表示自我处理或运算。</p> <pre style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;margin-top: 10px;margin-bottom: 10px;"><span style="display: block;background: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbskyvchl3yzerhnm8cv0eribia6kxszvzrfthxrcn46sxzylwhefibb5fp8bicgummdghws2e8cur8qzy02zdldnaria 640?wx_fmt="svg&from=appmsg")" 10px 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;></span><code style="overflow-x: auto;color: rgb(171, 178, 191);width: auto;margin-left: 2px;margin-right: 2px;padding: 15px 4px 2px;border-style: none;border-width: 3px;border-color: rgb(0, 0, 0) rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4);word-break: break-all;background: rgb(40, 44, 52);display: -webkit-box;font-family: " operator mono, consolas, monaco, menlo, monospace;border-radius: 0px;font-size: 12px;>A ->A: 自调用<br></code></pre> <figure style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012117" data-ratio="2.0406976744186047" src="/upload/b139dc43cef7646d7004c800b1a840ef.png" data-type="png" data-w="172" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> 自调用 </figcaption> </figure> </section></li> </ul> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;background-attachment: scroll;background-clip: border-box;background-image: url(" https: mmbiz.qpic.cn mmbiz_png pmzoeonjxwc5p16tqysanspnkbrxfxxfh0iaicjh4eraszazhu0qdcliaibiaib5o7rqxib2tnmlej1x74xjyyonrdk9a 640?wx_fmt="png&from=appmsg");background-origin:" padding-box;background-position: 50% 50%;background-repeat: no-repeat;background-size: 63px;width: auto;height: auto;align-items: unset;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;justify-content: center;line-height: 1.5em;overflow: unset;text-shadow: none;transform: none;-webkit-box-reflect: unset;><span style="display: none;"></span><span style="font-size: 18px;color: rgb(72, 179, 120);line-height: 2.4em;letter-spacing: 0em;margin-top: 38px;margin-bottom: 10px;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;box-shadow: none;display: inline-block;font-weight: bold;flex-direction: unset;float: unset;height: 38px;justify-content: unset;overflow: unset;text-align: center;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset;">生命线(Lifeline)与激活条(Activation Bar)</span><span style="display: none;"></span></h2> <p data-tool="mdnice编辑器" style="color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;">在时序图中,生命线表示对象在一段时间内的活动状态,也就是从参与者往下延伸的那条虚线。激活条用来表示参与者或对象在处理某个任务期间的活动状态,是生命线的一部分,矩形条形式出现。</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> 生命线的激活与撤销:可以用下面这些关键字来控制生命线的激活与撤销 </section></li> <ul style="list-style-type: square;margin-top: 8px;margin-bottom: 8px;padding-left: 25px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> activate: 显示参与者的活动状态开始 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> deactivate: 指示参与者的活动状态结束。 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> destroy: 用于表示参与者的生命线终结,通常表示对象生命周期的结束。 </section></li> </ul> </ul> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;margin-top: 10px;margin-bottom: 10px;"><span style="display: block;background: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbskyvchl3yzerhnm8cv0eribia6kxszvzrfthxrcn46sxzylwhefibb5fp8bicgummdghws2e8cur8qzy02zdldnaria 640?wx_fmt="svg&from=appmsg")" 10px 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;font-size: 12px;"><span style="color: #61aeee;line-height: 26px;">@startuml</span><br>participant User<br>User -> A: DoWork<br>activate A<br>A -> B: << createRequest >><br>activate B<br>B -> C: DoWork<br>activate C<br>C --> B: WorkDone<br>destroy C<br>B --> A: RequestCreated<br>deactivate B<br>A -> User: Done<br>deactivate A<br><span style="color: #61aeee;line-height: 26px;">@enduml</span><br></code></pre> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012116" data-ratio="0.8515463917525773" src="/upload/c74387e681d903d2ff2526c17fae0bf2.png" data-type="png" data-w="485" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> 生命线的激活与撤销 </figcaption> </figure> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> 生命线的嵌套与颜色:我们还可以使用嵌套激活条来表示内部调用,并可以给生命线添加颜色。 </section></li> </ul> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;margin-top: 10px;margin-bottom: 10px;"><span style="display: block;background: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbskyvchl3yzerhnm8cv0eribia6kxszvzrfthxrcn46sxzylwhefibb5fp8bicgummdghws2e8cur8qzy02zdldnaria 640?wx_fmt="svg&from=appmsg")" 10px 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;font-size: 12px;"><span style="color: #61aeee;line-height: 26px;">@startuml</span><br>participant User<br>User -> A: DoWork<br>activate A #FFBBBB<br>A -> A: Internal call<br>activate A #DarkSalmon<br>A -> B: << createRequest >><br>activate B<br>B --> A: RequestCreated<br>deactivate B<br>deactivate A<br>A -> User: Done<br>deactivate A<br><span style="color: #61aeee;line-height: 26px;">@enduml</span><br><br></code></pre> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012122" data-ratio="1.088992974238876" src="/upload/604e66046aba4639d92f0cc693dd97db.png" data-type="png" data-w="427" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> 生命线的嵌套与颜色 </figcaption> </figure> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> 自动激活:在发送消息时自动显示激活条。 </section></li> </ul> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;margin-top: 10px;margin-bottom: 10px;"><span style="display: block;background: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbskyvchl3yzerhnm8cv0eribia6kxszvzrfthxrcn46sxzylwhefibb5fp8bicgummdghws2e8cur8qzy02zdldnaria 640?wx_fmt="svg&from=appmsg")" 10px 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;font-size: 12px;">A->B++: 激活B并发送消息<br></code></pre> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012120" data-ratio="0.8079268292682927" src="/upload/9e795f7d95d6d47f5785343fe21e8395.png" data-type="png" data-w="328" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> 自动激活 </figcaption> </figure> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> 自动去激活:在接收回应时自动隐藏激活条。 </section></li> </ul> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;margin-top: 10px;margin-bottom: 10px;"><span style="display: block;background: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbskyvchl3yzerhnm8cv0eribia6kxszvzrfthxrcn46sxzylwhefibb5fp8bicgummdghws2e8cur8qzy02zdldnaria 640?wx_fmt="svg&from=appmsg")" 10px 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;font-size: 12px;">A->B++: 激活B并发送消息<br>A <--B--: B去激活并回应消息<br></code></pre> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012124" data-ratio="0.9095890410958904" src="/upload/9f4defcf1a483d61662ea4eb3c146357.png" data-type="png" data-w="365" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> 自动去激活 </figcaption> </figure> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;background-attachment: scroll;background-clip: border-box;background-image: url(" https: mmbiz.qpic.cn mmbiz_png pmzoeonjxwc5p16tqysanspnkbrxfxxfh0iaicjh4eraszazhu0qdcliaibiaib5o7rqxib2tnmlej1x74xjyyonrdk9a 640?wx_fmt="png&from=appmsg");background-origin:" padding-box;background-position: 50% 50%;background-repeat: no-repeat;background-size: 63px;width: auto;height: auto;align-items: unset;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;justify-content: center;line-height: 1.5em;overflow: unset;text-shadow: none;transform: none;-webkit-box-reflect: unset;><span style="display: none;"></span><span style="font-size: 18px;color: rgb(72, 179, 120);line-height: 2.4em;letter-spacing: 0em;margin-top: 38px;margin-bottom: 10px;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;box-shadow: none;display: inline-block;font-weight: bold;flex-direction: unset;float: unset;height: 38px;justify-content: unset;overflow: unset;text-align: center;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset;">分组和替代</span><span style="display: none;"></span></h2> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> 分组:用于逻辑上分组一系列交互。 </section></li> </ul> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;margin-top: 10px;margin-bottom: 10px;"><span style="display: block;background: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbskyvchl3yzerhnm8cv0eribia6kxszvzrfthxrcn46sxzylwhefibb5fp8bicgummdghws2e8cur8qzy02zdldnaria 640?wx_fmt="svg&from=appmsg")" 10px 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;font-size: 12px;">group 分组名<br>A -> B: 消息<br>...<br>end group<br></code></pre> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012121" data-ratio="1.7433628318584071" src="/upload/e7100f2cfd0d21132a6aa6d7b66cec7e.png" data-type="png" data-w="226" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> 分组 </figcaption> </figure> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> 替代(Alt/Else):表示基于条件的替代执行流程。 </section></li> </ul> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;margin-top: 10px;margin-bottom: 10px;"><span style="display: block;background: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbskyvchl3yzerhnm8cv0eribia6kxszvzrfthxrcn46sxzylwhefibb5fp8bicgummdghws2e8cur8qzy02zdldnaria 640?wx_fmt="svg&from=appmsg")" 10px 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;font-size: 12px;">alt 条件<span style="color: #d19a66;line-height: 26px;">1</span><br>A -> B: 满足条件<span style="color: #d19a66;line-height: 26px;">1</span>的消息<br><span style="color: #c678dd;line-height: 26px;">else</span> 条件<span style="color: #d19a66;line-height: 26px;">2</span><br>A -> B: 满足条件<span style="color: #d19a66;line-height: 26px;">2</span>的消息<br>end<br></code></pre> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012123" data-ratio="1.1624203821656052" src="/upload/5fca183fc5a2d4f0e86c24b6c9434b45.png" data-type="png" data-w="314" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> 替代 </figcaption> </figure> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;background-attachment: scroll;background-clip: border-box;background-image: url(" https: mmbiz.qpic.cn mmbiz_png pmzoeonjxwc5p16tqysanspnkbrxfxxfh0iaicjh4eraszazhu0qdcliaibiaib5o7rqxib2tnmlej1x74xjyyonrdk9a 640?wx_fmt="png&from=appmsg");background-origin:" padding-box;background-position: 50% 50%;background-repeat: no-repeat;background-size: 63px;width: auto;height: auto;align-items: unset;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;justify-content: center;line-height: 1.5em;overflow: unset;text-shadow: none;transform: none;-webkit-box-reflect: unset;><span style="display: none;"></span><span style="font-size: 18px;color: rgb(72, 179, 120);line-height: 2.4em;letter-spacing: 0em;margin-top: 38px;margin-bottom: 10px;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;box-shadow: none;display: inline-block;font-weight: bold;flex-direction: unset;float: unset;height: 38px;justify-content: unset;overflow: unset;text-align: center;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset;">注释</span><span style="display: none;"></span></h2> <p data-tool="mdnice编辑器" style="color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;">注释用于添加说明性文本。</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> 可以用note left of,note right of或note over来控制注释相对节点的位置,还可以通过修改背景色来高亮显示注释。 </section></li> </ul> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;margin-top: 10px;margin-bottom: 10px;"><span style="display: block;background: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbskyvchl3yzerhnm8cv0eribia6kxszvzrfthxrcn46sxzylwhefibb5fp8bicgummdghws2e8cur8qzy02zdldnaria 640?wx_fmt="svg&from=appmsg")" 10px 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;font-size: 12px;"><span style="color: #61aeee;line-height: 26px;">@startuml</span><br>participant Alice<br>participant Bob<br>note left of Alice #aqua<br>This is displayed<br>left of Alice.<br>end note<br><br>note right of Alice: This is displayed right of Alice.<br><br>note over Alice: This is displayed over Alice.<br><br>note over Alice, Bob #FFAAAA: This is displayed\n over Bob and Alice.<br><br>note over Bob, Alice<br>This is yet another<br>example of<br>a <span style="color: #c678dd;line-height: 26px;">long</span> note.<br>end note<br><span style="color: #61aeee;line-height: 26px;">@enduml</span><br></code></pre> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012128" data-ratio="1.055441478439425" src="/upload/85fa9596bc9fe5d3ade903f06596066a.png" data-type="png" data-w="487" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> 注释 </figcaption> </figure> <h2 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;background-attachment: scroll;background-clip: border-box;background-image: url(" https: mmbiz.qpic.cn mmbiz_png pmzoeonjxwc5p16tqysanspnkbrxfxxfh0iaicjh4eraszazhu0qdcliaibiaib5o7rqxib2tnmlej1x74xjyyonrdk9a 640?wx_fmt="png&from=appmsg");background-origin:" padding-box;background-position: 50% 50%;background-repeat: no-repeat;background-size: 63px;width: auto;height: auto;align-items: unset;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;justify-content: center;line-height: 1.5em;overflow: unset;text-shadow: none;transform: none;-webkit-box-reflect: unset;><span style="display: none;"></span><span style="font-size: 18px;color: rgb(72, 179, 120);line-height: 2.4em;letter-spacing: 0em;margin-top: 38px;margin-bottom: 10px;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;box-shadow: none;display: inline-block;font-weight: bold;flex-direction: unset;float: unset;height: 38px;justify-content: unset;overflow: unset;text-align: center;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset;">颜色</span><span style="display: none;"></span></h2> <p data-tool="mdnice编辑器" style="color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;">Choosing colors在 PlantUML 中,我们可以对时序图的各个元素自定义颜色,比如参与者(actors)、对象(objects)、激活条(activation bars)等,来让我们的时序图更加美观。在声明元素时,可以直接指定颜色,格式为#颜色代码。颜色代码可以是不同的形式:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> 直接指定颜色:颜色代码可以是一个十六进制颜色值,也可以是预定义的颜色名称。 </section></li> </ul> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;margin-top: 10px;margin-bottom: 10px;"><span style="display: block;background: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbskyvchl3yzerhnm8cv0eribia6kxszvzrfthxrcn46sxzylwhefibb5fp8bicgummdghws2e8cur8qzy02zdldnaria 640?wx_fmt="svg&from=appmsg")" 10px 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;font-size: 12px;"><span style="color: #61aeee;line-height: 26px;">@startuml</span><br>actor 用户 #Green<br>participant 参与者 #B4A7E5<br><br>用户-[#red]>参与者:消息<br>activate 参与者 #Blue<br><br><span style="color: #61aeee;line-height: 26px;">@enduml</span><br></code></pre> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012125" data-ratio="1.9739130434782608" src="/upload/44f17b8e66ed9c747c0815e9dc0c7e64.png" data-type="png" data-w="230" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> 直接指定颜色 </figcaption> </figure> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> 使用 <code style="background: none 0% 0% / auto no-repeat scroll padding-box border-box rgba(27, 31, 35, 0.05);width: auto;margin-left: 2px;margin-right: 2px;padding: 2px 4px;border-style: none;border-width: 3px;border-color: rgb(0, 0, 0) rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4);border-radius: 4px;font-family: " operator mono, consolas, monaco, menlo, monospace;word-break: break-all;>skinparam</code> 设置颜色:除了直接为特定元素指定颜色外,还可以使用 <code style="background: none 0% 0% / auto no-repeat scroll padding-box border-box rgba(27, 31, 35, 0.05);width: auto;margin-left: 2px;margin-right: 2px;padding: 2px 4px;border-style: none;border-width: 3px;border-color: rgb(0, 0, 0) rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4);border-radius: 4px;font-family: " operator mono, consolas, monaco, menlo, monospace;word-break: break-all;>skinparam</code> 全局设置时序图中的颜色。用这种方式更改元素的默认颜色比较方便: </section></li> </ul> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;margin-top: 10px;margin-bottom: 10px;"><span style="display: block;background: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbskyvchl3yzerhnm8cv0eribia6kxszvzrfthxrcn46sxzylwhefibb5fp8bicgummdghws2e8cur8qzy02zdldnaria 640?wx_fmt="svg&from=appmsg")" 10px 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;font-size: 12px;"><span style="color: #61aeee;line-height: 26px;">@startuml</span><br>skinparam ActorBorderColor #DarkOrange<br>skinparam ParticipantBackgroundColor #SkyBlue<br><br>actor 用户<br>participant 参与者<br><span style="color: #61aeee;line-height: 26px;">@enduml</span><br></code></pre> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012127" data-ratio="1.6869565217391305" src="/upload/05d2d28b9266bdc76217160a91f84a2b.png" data-type="png" data-w="230" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> 使用 <code>skinparam</code> 设置颜色 </figcaption> </figure> <p data-tool="mdnice编辑器" style="color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;">当使用 <code style="color: rgb(40, 202, 113);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background: none 0% 0% / auto no-repeat scroll padding-box border-box rgba(27, 31, 35, 0.05);width: auto;height: auto;margin-left: 2px;margin-right: 2px;padding: 2px 4px;border-style: none;border-width: 3px;border-color: rgb(0, 0, 0) rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4);border-radius: 4px;font-family: " operator mono, consolas, monaco, menlo, monospace;word-break: break-all;>skinparam</code> 时,我们可以设置许多不同属性的颜色,如边框颜色(BorderColor)、背景颜色(BackgroundColor)、字体颜色(FontColor)和激活条颜色(SequenceGroupBodyBackgroundColor)。更多语法可以直接查看官方文档:顺序图的语法和功能,目前这些内容,已经足够我们常见的时序图需求了。</p> <h1 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;background-attachment: scroll;background-clip: border-box;background-image: url(" https: mmbiz.qpic.cn mmbiz_jpg pmzoeonjxwc5p16tqysanspnkbrxfxxfqzjf2xcbjibnwrswd6iciajlnr8lhjoqg8nhwqaido8ow6kizvibyvc0yq 640?wx_fmt="other&from=appmsg");background-origin:" padding-box;background-position: 50% 50%;background-repeat: no-repeat;background-size: 75px;width: auto;height: auto;align-items: unset;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;justify-content: center;line-height: 1.5em;overflow: unset;text-shadow: none;transform: none;-webkit-box-reflect: unset;><span style="display: none;"></span><span style="font-size: 18px;color: rgb(72, 179, 120);line-height: 2.4em;letter-spacing: 0em;margin-top: 38px;margin-bottom: 10px;border-style: none none solid;border-width: 1px 1px 2px;border-color: rgb(0, 0, 0) rgb(0, 0, 0) rgb(46, 121, 80);border-radius: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;box-shadow: none;display: inline-block;font-weight: bold;flex-direction: unset;float: unset;height: 38px;justify-content: unset;overflow: unset;text-align: center;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset;">四、完整实例</span><span style="display: none;"></span></h1> <p data-tool="mdnice编辑器" style="color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;">我们接下来看一个稍微完整一点的例子,在这个例子中,我们的需求,是要在原本的登录的基础上,引入Google登录。</p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;margin-top: 10px;margin-bottom: 10px;"><span style="display: block;background: url(" https: mmbiz.qpic.cn mmbiz_svg iahdqiccc5vbskyvchl3yzerhnm8cv0eribia6kxszvzrfthxrcn46sxzylwhefibb5fp8bicgummdghws2e8cur8qzy02zdldnaria 640?wx_fmt="svg&from=appmsg")" 10px 40px no-repeat rgb(40, 44, 52);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;font-size: 12px;"><span style="color: #61aeee;line-height: 26px;">@startuml</span><br>skinparam ParticipantBackgroundColor #DeepSkyBlue<br><br>actor 用户 as c #DeepSkyBlue<br>participant <span style="color: #98c379;line-height: 26px;">"客户端"</span> as client<br>participant <span style="color: #98c379;line-height: 26px;">"服务网关"</span> as ga<br>participant <span style="color: #98c379;line-height: 26px;">"用户服务"</span> as user<br>database <span style="color: #98c379;line-height: 26px;">"数据库"</span> as DB #DeepSkyBlue<br>participant <span style="color: #98c379;line-height: 26px;">"Google服务"</span> as google #LightCoral<br><br>activate c #DeepSkyBlue<br>activate client #DeepSkyBlue<br><br>c->client:用户登录<br><br>group#LightCoral #LightCoral Google登录客户端流程<br> client -> google : 请求Google OAuth登录<br> activate google #DeepSkyBlue<br> google-->client:登录url<br> client->google:跳转登录页<br> google -> google : 用户登录<br> google --> client : Google登录Token<br> deactivate google<br>end<br><br>|||<br><br>client -> ga : 登录请求<br>note right#LightCoral:新增登录方式,三方登录请求实体<br>activate ga #DeepSkyBlue<br>ga ->user:请求转发<br>activate user #DeepSkyBlue<br><br><br>alt#DeepSkyBlue 常规登录<br> user -> DB : 查询用户信息<br> activate DB #DeepSkyBlue<br> DB -> user : 用户信息<br> deactivate DB<br> user->user:登录密码校验<br><br>|||<br><span style="color: #c678dd;line-height: 26px;">else</span> Google登录<br> group#LightCoral #LightCoral Google登录服务端流程<br> user->google:验证token<br> activate google #DeepSkyBlue<br> google-->user:用户信息<br> deactivate google<br> user->user:存储或更新用户信息<br> end group<br>end<br><br><br>user-->ga:登录结果<br>deactivate user<br>ga -> client : 响应<br>deactivate ga<br>alt#DeepSkyBlue 成功<br> client -> c : 登录成功<br><span style="color: #c678dd;line-height: 26px;">else</span> 失败<br> client -> c : 登录失败<br>end<br>deactivate client<br>|||<br><span style="color: #61aeee;line-height: 26px;">@enduml</span><br><br><br></code></pre> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <img class="rich_pages wxw-img" data-imgfileid="100012129" data-ratio="1.7737512242899118" src="/upload/d35a0f3d54b426c0500f40eb0cf93576.png" data-type="png" data-w="1021" style="display: block;margin-right: auto;margin-left: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 4px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"> <figcaption style="color: rgb(136, 136, 136);font-size: 12px;line-height: 1.5em;letter-spacing: 0em;text-align: center;margin-top: 5px;"> 登录时序图 </figcaption> </figure> <h1 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;background-attachment: scroll;background-clip: border-box;background-image: url(" https: mmbiz.qpic.cn mmbiz_jpg pmzoeonjxwc5p16tqysanspnkbrxfxxfqzjf2xcbjibnwrswd6iciajlnr8lhjoqg8nhwqaido8ow6kizvibyvc0yq 640?wx_fmt="other&from=appmsg");background-origin:" padding-box;background-position: 50% 50%;background-repeat: no-repeat;background-size: 75px;width: auto;height: auto;align-items: unset;border-style: none;border-width: 1px;border-color: rgb(0, 0, 0);border-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;justify-content: center;line-height: 1.5em;overflow: unset;text-shadow: none;transform: none;-webkit-box-reflect: unset;><span style="display: none;"></span><span style="font-size: 18px;color: rgb(72, 179, 120);line-height: 2.4em;letter-spacing: 0em;margin-top: 38px;margin-bottom: 10px;border-style: none none solid;border-width: 1px 1px 2px;border-color: rgb(0, 0, 0) rgb(0, 0, 0) rgb(46, 121, 80);border-radius: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;box-shadow: none;display: inline-block;font-weight: bold;flex-direction: unset;float: unset;height: 38px;justify-content: unset;overflow: unset;text-align: center;text-indent: 0em;text-shadow: none;transform: none;width: auto;-webkit-box-reflect: unset;">五、总结</span><span style="display: none;"></span></h1> <p data-tool="mdnice编辑器" style="color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;">PlantUML使用起来整体上还是非常舒服的,对我而言,这几个特点让我爱不释手:</p> <ul data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> 提供了类似MarkDown的所见即所得的使用体验,免去调整图形之扰 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> PlantUML本质是文本,可以进行版本控制,多人协同 </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> 语雀支持文本画图的功能,可以嵌入PlantUML文本,支持在语雀文档里直接修改 </section></li> </ul> <p data-tool="mdnice编辑器" style="color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;">PlantUML还有很强大的扩展性和灵活性,我们可以通过 官方文档:<span style="color: rgb(91, 128, 141);font-family: Vollkorn, Palatino, Times;letter-spacing: normal;orphans: 4;text-align: start;white-space: pre-wrap;word-spacing: 0.85px;background-color: rgb(255, 255, 255);text-decoration: underline;">https://plantuml.com/zh/</span> 继续探索更多高级语法和技巧,来绘制更加复杂和丰富的图表。</p> <hr data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-style: none;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-color: rgb(0, 0, 0) rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4);border-radius: 0px;background: linear-gradient(90deg, rgba(93, 186, 133, 0) 0%, rgba(93, 186, 133, 0.75) 50%, rgba(93, 186, 133, 0) 100%) 0% 0% / auto no-repeat scroll padding-box border-box rgba(255, 255, 255, 0);width: auto;height: 2px;"> <p data-tool="mdnice编辑器" style="color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;text-indent: 0em;padding-top: 16px;padding-bottom: 8px;"><strong style="color: rgb(74, 74, 74);background-attachment: scroll;background-clip: border-box;background-image: none;background-origin: padding-box;background-position: 0% 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;border-style: none;border-width: 3px;border-color: rgba(0, 0, 0, 0.4);border-radius: 0px;">参考:</strong></p> <ol data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;" class="list-paddingleft-1"> <li style="font-size: 10px;"> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> <span style="font-size: 10px;">开源工具,使用简单的文字描述画UML图</span> </section></li> <li style="font-size: 10px;"> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> <span style="font-size: 10px;">Choosing colors</span> </section></li> <li style="font-size: 10px;"> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> <span style="font-size: 10px;">顺序图的语法和功能</span> </section></li> <li style="font-size: 10px;"> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> <span style="font-size: 10px;">如何使用 PlantUML 画系统设计图?- 掘金</span> </section></li> <li style="font-size: 10px;"> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> <span style="font-size: 10px;">顺序图的语法和功能</span> </section></li> <li style="font-size: 10px;"> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(63, 63, 63);line-height: 1.8em;letter-spacing: 0.02em;"> <span style="font-size: 10px;">GPT老师</span> </section></li> </ol> </section>
作者:微信小助手
<p style="margin-bottom: 0px;letter-spacing: 0.578px;text-wrap: wrap;text-align: center;"><span leaf=""><img class="rich_pages wxw-img" data-imgfileid="100015609" data-ratio="0.5714285714285714" data-s="300,640" src="/upload/5e98b50f0a7c61f3ccf1310a77e91fa9.png" data-type="png" data-w="1792" style="height: 330px;width: 578px;"></span></p> <section style="margin-bottom: 0px;letter-spacing: 0.578px;text-wrap: wrap;line-height: 2em;"> <span style="letter-spacing: 0.578px;font-family: mp-quote, -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: var(--articlefontsize);><span leaf=""><br></span></span> </section> <p data-sourcepos="1:1-1:75" style="box-sizing: border-box;margin-top: 0px !important;margin-bottom: 1rem;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-size: 16px;font-style: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><strong style="box-sizing: border-box;font-weight: 600;color: rgb(51, 51, 51);"><span leaf="">SpringBoot 实现 License 认证:快速校验有效期的简洁方案</span></strong></p> <p data-sourcepos="3:1-3:789" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-size: 16px;font-style: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span leaf="">在现代软件开发中,特别是商业软件领域,</span><strong style="box-sizing: border-box;font-weight: 600;color: rgb(51, 51, 51);"><span leaf="">License认证</span></strong><span leaf="">是一种至关重要的技术,用于限制软件的使用范围和授权模式。它不仅保护开发者的利益,也为用户提供合法使用的依据。License认证通常涉及生成密钥对、签发证书以及验证有效性等步骤,这些过程虽然复杂,但通过适当的工具和技术可以简化实现。在本篇文章中,我们将基于</span><span leaf=""> </span><strong style="box-sizing: border-box;font-weight: 600;color: rgb(51, 51, 51);"><span leaf="">SpringBoot</span></strong><span leaf=""> </span><span leaf="">框架,结合</span><span leaf=""> </span><strong style="box-sizing: border-box;font-weight: 600;color: rgb(51, 51, 51);"><span leaf="">TrueLicense</span></strong><span leaf=""> </span><span leaf="">开源工具,展示如何快速实现 License 认证,尤其是围绕“有效期校验”的核心功能。通过阅读本文,您将掌握如何生成密钥对、创建 License 证书以及如何在项目中集成并校验证书的有效性,助力您构建更加安全可靠的软件系统。</span></p> <h3 data-sourcepos="5:1-5:18" style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1rem;font-weight: 600;line-height: 1.25;font-size: 1.25rem;color: rgb(5, 149, 191);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-style: normal;font-variant-caps: normal;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span style="box-sizing: border-box;display: inline-block;fill: currentcolor;vertical-align: middle;color: rgb(5, 149, 191);visibility: hidden;"></span><span leaf="">License 简介</span></h3> <p data-sourcepos="7:1-7:104" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-size: 16px;font-style: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span leaf="">License 即版权许可证书,用于为收费软件提供访问许可证明,常见于以下场景:</span></p> <ul style="box-sizing: border-box;padding-left: 2rem;margin-top: 0px;margin-bottom: 1rem;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-size: 16px;font-style: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none; class="list-paddingleft-1"> <li style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: 600;color: rgb(51, 51, 51);"><span leaf="">应用场景</span></strong> <section> <span leaf=""><br></span> <section> <span leaf="">部署在客户内网环境,开发者无法控制其网络状态,需通过离线方式校验证书有效性。</span> </section> </section></li> <li style="box-sizing: border-box;margin-top: 0.25rem;"><strong style="box-sizing: border-box;font-weight: 600;color: rgb(51, 51, 51);"><span leaf="">授权原理</span></strong> <section> <span leaf=""><br></span> <section> <span leaf="">利用证书管理工具生成密钥对,私钥用于创建 License 证书,公钥验证其合法性和有效期。</span> </section> </section></li> </ul> <h3 data-sourcepos="14:1-14:28" style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1rem;font-weight: 600;line-height: 1.25;font-size: 1.25rem;color: rgb(5, 149, 191);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-style: normal;font-variant-caps: normal;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span style="box-sizing: border-box;display: inline-block;fill: currentcolor;vertical-align: middle;color: rgb(5, 149, 191);visibility: hidden;"></span><span leaf="">授权者生成密钥对</span></h3> <p data-sourcepos="16:1-16:86" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-size: 16px;font-style: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span leaf="">授权者通过</span><span leaf=""> </span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, monospace;font-size: 13.6px;padding: 0.2rem 0.4rem;margin: 0px;background-color: rgb(247, 248, 248);color: rgb(9, 132, 79);border-radius: 0.1875rem;><span leaf="">Keytool</span></code><span leaf=""> </span><span leaf="">工具生成私钥和公钥,并完成证书库的管理。</span></p> <pre data-sourcepos="18:1-28:3" tabindex="0" style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;margin: 0.5rem 0px;overflow-wrap: normal;padding: 1rem;overflow: auto;line-height: 1.45;background: rgb(247, 248, 248);border-radius: 0.1875rem;color: black;text-align: left;word-spacing: normal;word-break: normal;tab-size: 4;hyphens: none;><code style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;padding: 0px;margin: 0px;background-color: initial;color: rgb(9, 132, 79);border-radius: 0.1875rem;background-image: none;background-position: 0% 0%;background-size: auto;background-repeat: repeat;background-attachment: scroll;background-origin: padding-box;background-clip: border-box;text-align: left;word-spacing: normal;word-break: normal;overflow-wrap: normal;tab-size: 4;hyphens: none;border: 0px;display: inline;overflow: visible;line-height: inherit;><span style="box-sizing: border-box;color: rgb(142, 156, 146);"><span leaf=""># 生成私钥库</span></span><span leaf=""><br></span><span leaf="">keytool </span><span style="box-sizing: border-box;color: rgb(120, 72, 48);"><span leaf="">-genkeypair</span></span><span style="box-sizing: border-box;color: rgb(120, 72, 48);"><span leaf="">-keysize</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">2048</span></span><span style="box-sizing: border-box;color: rgb(120, 72, 48);"><span leaf="">-validity</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">3650</span></span><span style="box-sizing: border-box;color: rgb(120, 72, 48);"><span leaf="">-alias</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"privateKey"</span></span><span style="box-sizing: border-box;color: rgb(120, 72, 48);"><span leaf="">-keystore</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"privateKeys.keystore"</span></span><span style="box-sizing: border-box;color: rgb(120, 72, 48);"><span leaf="">-storepass</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"myStorePass123"</span></span><span style="box-sizing: border-box;color: rgb(120, 72, 48);"><span leaf="">-keypass</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"myKeyPass123"</span></span><span style="box-sizing: border-box;color: rgb(120, 72, 48);"><span leaf="">-dname</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"CN=localhost, OU=localhost, O=localhost, L=SH, ST=SH, C=CN"</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(142, 156, 146);"><span leaf=""># 导出公钥到文件</span></span><span leaf=""><br></span><span leaf="">keytool </span><span style="box-sizing: border-box;color: rgb(120, 72, 48);"><span leaf="">-exportcert</span></span><span style="box-sizing: border-box;color: rgb(120, 72, 48);"><span leaf="">-alias</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"privateKey"</span></span><span style="box-sizing: border-box;color: rgb(120, 72, 48);"><span leaf="">-keystore</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"privateKeys.keystore"</span></span><span style="box-sizing: border-box;color: rgb(120, 72, 48);"><span leaf="">-storepass</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"myStorePass123"</span></span><span style="box-sizing: border-box;color: rgb(120, 72, 48);"><span leaf="">-file</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"certfile.cer"</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(142, 156, 146);"><span leaf=""># 导入证书到公钥库</span></span><span leaf=""><br></span><span leaf="">keytool </span><span style="box-sizing: border-box;color: rgb(120, 72, 48);"><span leaf="">-import</span></span><span style="box-sizing: border-box;color: rgb(120, 72, 48);"><span leaf="">-alias</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"publicCert"</span></span><span style="box-sizing: border-box;color: rgb(120, 72, 48);"><span leaf="">-file</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"certfile.cer"</span></span><span style="box-sizing: border-box;color: rgb(120, 72, 48);"><span leaf="">-keystore</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"publicCerts.keystore"</span></span><span style="box-sizing: border-box;color: rgb(120, 72, 48);"><span leaf="">-storepass</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"myStorePass123"</span></span><span leaf=""><br></span><span leaf=""><br></span></code></pre> <h3 data-sourcepos="30:1-30:34" style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1rem;font-weight: 600;line-height: 1.25;font-size: 1.25rem;color: rgb(5, 149, 191);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-style: normal;font-variant-caps: normal;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span style="box-sizing: border-box;display: inline-block;fill: currentcolor;vertical-align: middle;color: rgb(5, 149, 191);visibility: hidden;"></span><span leaf="">授权者生成 License 文件</span></h3> <h4 data-sourcepos="32:1-32:17" style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1rem;font-weight: 600;line-height: 1.25;font-size: 16px;color: rgb(5, 149, 191);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-style: normal;font-variant-caps: normal;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span style="box-sizing: border-box;display: inline-block;fill: currentcolor;vertical-align: middle;color: rgb(5, 149, 191);visibility: hidden;"></span><span leaf="">Maven 依赖</span></h4> <p data-sourcepos="34:1-34:74" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-size: 16px;font-style: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span leaf="">在项目的</span><span leaf=""> </span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, monospace;font-size: 13.6px;padding: 0.2rem 0.4rem;margin: 0px;background-color: rgb(247, 248, 248);color: rgb(9, 132, 79);border-radius: 0.1875rem;><span leaf="">pom.xml</span></code><span leaf=""> </span><span leaf="">文件中添加</span><span leaf=""> </span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, monospace;font-size: 13.6px;padding: 0.2rem 0.4rem;margin: 0px;background-color: rgb(247, 248, 248);color: rgb(9, 132, 79);border-radius: 0.1875rem;><span leaf="">TrueLicense</span></code><span leaf=""> </span><span leaf="">的核心库依赖:</span></p> <pre data-sourcepos="36:1-42:3" tabindex="0" style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;margin: 0.5rem 0px;overflow-wrap: normal;padding: 1rem;overflow: auto;line-height: 1.45;background: rgb(247, 248, 248);border-radius: 0.1875rem;color: black;text-align: left;word-spacing: normal;word-break: normal;tab-size: 4;hyphens: none;><code style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;padding: 0px;margin: 0px;background-color: initial;color: rgb(9, 132, 79);border-radius: 0.1875rem;background-image: none;background-position: 0% 0%;background-size: auto;background-repeat: repeat;background-attachment: scroll;background-origin: padding-box;background-clip: border-box;text-align: left;word-spacing: normal;word-break: normal;overflow-wrap: normal;tab-size: 4;hyphens: none;border: 0px;display: inline;overflow: visible;line-height: inherit;><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf=""><</span></span><span leaf="">dependency</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">></span></span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf=""><</span></span><span leaf="">groupId</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">></span></span></span><span leaf="">de.schlichtherle.truelicense</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf=""><!--/</span--></span><span leaf="">groupId</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">></span></span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf=""><</span></span><span leaf="">artifactId</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">></span></span></span><span leaf="">truelicense-core</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf=""><!--/</span--></span><span leaf="">artifactId</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">></span></span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf=""><</span></span><span leaf="">version</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">></span></span></span><span leaf="">1.33</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf=""><!--/</span--></span><span leaf="">version</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">></span></span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf=""><!--/</span--></span><span leaf="">dependency</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">></span></span></span><span leaf=""><br></span></span></span></span></span></code></pre> <p data-sourcepos="44:1-44:17" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-size: 16px;font-style: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span leaf="">License 生成类</span></p> <p data-sourcepos="46:1-46:56" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-size: 16px;font-style: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span leaf="">以下代码实现了</span><span leaf=""> </span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, monospace;font-size: 13.6px;padding: 0.2rem 0.4rem;margin: 0px;background-color: rgb(247, 248, 248);color: rgb(9, 132, 79);border-radius: 0.1875rem;><span leaf="">License</span></code><span leaf=""> </span><span leaf="">文件的生成逻辑。</span></p> <pre data-sourcepos="48:1-124:3" tabindex="0" style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;margin: 0.5rem 0px;overflow-wrap: normal;padding: 1rem;overflow: auto;line-height: 1.45;background: rgb(247, 248, 248);border-radius: 0.1875rem;color: black;text-align: left;word-spacing: normal;word-break: normal;tab-size: 4;hyphens: none;><code style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;padding: 0px;margin: 0px;background-color: initial;color: rgb(9, 132, 79);border-radius: 0.1875rem;background-image: none;background-position: 0% 0%;background-size: auto;background-repeat: repeat;background-attachment: scroll;background-origin: padding-box;background-clip: border-box;text-align: left;word-spacing: normal;word-break: normal;overflow-wrap: normal;tab-size: 4;hyphens: none;border: 0px;display: inline;overflow: visible;line-height: inherit;><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">package</span></span><span leaf=""> </span><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">com</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">icoderoad</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">license</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">de</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">schlichtherle</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">license</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;"><span leaf="">*</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">lombok</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">extern</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">slf4j</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Slf4j</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">javax</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">security</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">auth</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">x500</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">X500Principal</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">java</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">io</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">File</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">java</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">util</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Date</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">java</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">util</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">prefs</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Preferences</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Slf4j</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">class</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseCreator</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">static</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">final</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">X500Principal</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">DEFAULT_HOLDER_AND_ISSUER</span></span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">X500Principal</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"CN=localhost, OU=localhost, O=localhost, L=SH, ST=SH, C=CN"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">static</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">void</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">main</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">[</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">]</span></span><span leaf=""> args</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseCreatorParam</span></span><span leaf=""> param </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseCreatorParam</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setSubject</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"license"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setPrivateAlias</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"privateKey"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setKeyPass</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"myKeyPass123"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setStorePass</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"myStorePass123"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setLicensePath</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"license.lic"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setPrivateKeysStorePath</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"privateKeys.keystore"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setIssuedTime</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Date</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setExpiryTime</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Date</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">System</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">currentTimeMillis</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;"><span leaf="">+</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">10L</span></span><span style="box-sizing: border-box;"><span leaf="">*</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">365</span></span><span style="box-sizing: border-box;"><span leaf="">*</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">24</span></span><span style="box-sizing: border-box;"><span leaf="">*</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">60</span></span><span style="box-sizing: border-box;"><span leaf="">*</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">60</span></span><span style="box-sizing: border-box;"><span leaf="">*</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">1000</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setConsumerType</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"user"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setConsumerAmount</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">1</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setDescription</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"This is a license file."</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">try</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseCreator</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">generateLicense</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> log</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">info</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"License file generated successfully at: {}"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getLicensePath</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">catch</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Exception</span></span><span leaf=""> e</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> log</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">error</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"Failed to generate license file"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""> e</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">void</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">generateLicense</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseCreatorParam</span></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">try</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseManager</span></span><span leaf=""> licenseManager </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseManager</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">initLicenseParam</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseContent</span></span><span leaf=""> licenseContent </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">initLicenseContent</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> licenseManager</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">store</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">licenseContent</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">File</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getLicensePath</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">catch</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Exception</span></span><span leaf=""> e</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> log</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">error</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"License generation failed"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""> e</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">static</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseParam</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">initLicenseParam</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseCreatorParam</span></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Preferences</span></span><span leaf=""> preferences </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Preferences</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">userNodeForPackage</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseCreator</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">class</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">CipherParam</span></span><span leaf=""> cipherParam </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">DefaultCipherParam</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getStorePass</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">KeyStoreParam</span></span><span leaf=""> privateStoreParam </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">CustomKeyStoreParam</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseCreator</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">class</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getPrivateKeysStorePath</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getPrivateAlias</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getStorePass</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getKeyPass</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">return</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">DefaultLicenseParam</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getSubject</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""> preferences</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""> privateStoreParam</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""> cipherParam</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">static</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseContent</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">initLicenseContent</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseCreatorParam</span></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseContent</span></span><span leaf=""> content </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseContent</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> content</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setHolder</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">DEFAULT_HOLDER_AND_ISSUER</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> content</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setIssuer</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">DEFAULT_HOLDER_AND_ISSUER</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> content</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setSubject</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getSubject</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> content</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setIssued</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getIssuedTime</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> content</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setNotBefore</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getIssuedTime</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> content</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setNotAfter</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getExpiryTime</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> content</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setConsumerType</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getConsumerType</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> content</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setConsumerAmount</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getConsumerAmount</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> content</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setInfo</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getDescription</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">return</span></span><span leaf=""> content</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span></code></pre> <h4 data-sourcepos="126:1-126:28" style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1rem;font-weight: 600;line-height: 1.25;font-size: 16px;color: rgb(5, 149, 191);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-style: normal;font-variant-caps: normal;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span style="box-sizing: border-box;display: inline-block;fill: currentcolor;vertical-align: middle;color: rgb(5, 149, 191);visibility: hidden;"></span><span leaf="">LicenseCreatorParam 类</span></h4> <pre data-sourcepos="128:1-152:3" tabindex="0" style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;margin: 0.5rem 0px;overflow-wrap: normal;padding: 1rem;overflow: auto;line-height: 1.45;background: rgb(247, 248, 248);border-radius: 0.1875rem;color: black;text-align: left;word-spacing: normal;word-break: normal;tab-size: 4;hyphens: none;><code style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;padding: 0px;margin: 0px;background-color: initial;color: rgb(9, 132, 79);border-radius: 0.1875rem;background-image: none;background-position: 0% 0%;background-size: auto;background-repeat: repeat;background-attachment: scroll;background-origin: padding-box;background-clip: border-box;text-align: left;word-spacing: normal;word-break: normal;overflow-wrap: normal;tab-size: 4;hyphens: none;border: 0px;display: inline;overflow: visible;line-height: inherit;><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">package</span></span><span leaf=""> </span><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">com</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">icoderoad</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">license</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">com</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">fasterxml</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">jackson</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">annotation</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">JsonFormat</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">lombok</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Data</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">java</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">util</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Date</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Data</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">class</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseCreatorParam</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> subject</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> privateAlias</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> keyPass</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> storePass</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> licensePath</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> privateKeysStorePath</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@JsonFormat</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">pattern </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"yyyy-MM-dd HH:mm:ss"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""> timezone </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"GMT+8"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Date</span></span><span leaf=""> issuedTime</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@JsonFormat</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">pattern </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"yyyy-MM-dd HH:mm:ss"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""> timezone </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"GMT+8"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Date</span></span><span leaf=""> expiryTime</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> consumerType</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Integer</span></span><span leaf=""> consumerAmount</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> description</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span></code></pre> <h4 data-sourcepos="154:1-154:28" style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1rem;font-weight: 600;line-height: 1.25;font-size: 16px;color: rgb(5, 149, 191);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-style: normal;font-variant-caps: normal;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span style="box-sizing: border-box;display: inline-block;fill: currentcolor;vertical-align: middle;color: rgb(5, 149, 191);visibility: hidden;"></span><span leaf="">CustomKeyStoreParam 类</span></h4> <pre data-sourcepos="156:1-191:3" tabindex="0" style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;margin: 0.5rem 0px;overflow-wrap: normal;padding: 1rem;overflow: auto;line-height: 1.45;background: rgb(247, 248, 248);border-radius: 0.1875rem;color: black;text-align: left;word-spacing: normal;word-break: normal;tab-size: 4;hyphens: none;><code style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;padding: 0px;margin: 0px;background-color: initial;color: rgb(9, 132, 79);border-radius: 0.1875rem;background-image: none;background-position: 0% 0%;background-size: auto;background-repeat: repeat;background-attachment: scroll;background-origin: padding-box;background-clip: border-box;text-align: left;word-spacing: normal;word-break: normal;overflow-wrap: normal;tab-size: 4;hyphens: none;border: 0px;display: inline;overflow: visible;line-height: inherit;><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">package</span></span><span leaf=""> </span><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">com</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">icoderoad</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">license</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">de</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">schlichtherle</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">license</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">AbstractKeyStoreParam</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">class</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">CustomKeyStoreParam</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">extends</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">AbstractKeyStoreParam</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">final</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> storePath</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">final</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> alias</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">final</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> storePwd</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">final</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> keyPwd</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">CustomKeyStoreParam</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Class</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf=""><</span></span><span style="box-sizing: border-box;"><span leaf="">?</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">></span></span></span><span leaf=""> clazz</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> storePath</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> alias</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> storePwd</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> keyPwd</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">super</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">clazz</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""> storePath</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">this</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">storePath </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span leaf=""> storePath</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">this</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">alias </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span leaf=""> alias</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">this</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">storePwd </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span leaf=""> storePwd</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">this</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">keyPwd </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span leaf=""> keyPwd</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Override</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getAlias</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">return</span></span><span leaf=""> alias</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Override</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getStorePwd</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">return</span></span><span leaf=""> storePwd</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Override</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getKeyPwd</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">return</span></span><span leaf=""> keyPwd</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span></code></pre> <h3 data-sourcepos="193:1-193:25" style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1rem;font-weight: 600;line-height: 1.25;font-size: 1.25rem;color: rgb(5, 149, 191);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-style: normal;font-variant-caps: normal;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span style="box-sizing: border-box;display: inline-block;fill: currentcolor;vertical-align: middle;color: rgb(5, 149, 191);visibility: hidden;"></span><span leaf="">使用者配置验证</span></h3> <p data-sourcepos="195:1-195:116" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-size: 16px;font-style: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span leaf="">使用者需在项目中加载</span><span leaf=""> </span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, monospace;font-size: 13.6px;padding: 0.2rem 0.4rem;margin: 0px;background-color: rgb(247, 248, 248);color: rgb(9, 132, 79);border-radius: 0.1875rem;><span leaf="">publicKeys.keystore</span></code><span leaf=""> </span><span leaf="">和</span><span leaf=""> </span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, monospace;font-size: 13.6px;padding: 0.2rem 0.4rem;margin: 0px;background-color: rgb(247, 248, 248);color: rgb(9, 132, 79);border-radius: 0.1875rem;><span leaf="">license.lic</span></code><span leaf=""> </span><span leaf="">文件,并在应用启动时进行校验。</span></p> <ul style="box-sizing: border-box;padding-left: 2rem;margin-top: 0px;margin-bottom: 1rem;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-size: 16px;font-style: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none; class="list-paddingleft-1"> <li style="box-sizing: border-box;"><strong style="box-sizing: border-box;font-weight: 600;color: rgb(51, 51, 51);"><span leaf="">校验逻辑</span></strong> <section> <span leaf="">:通过公钥验证证书的合法性及有效期。</span> </section></li> <li style="box-sizing: border-box;margin-top: 0.25rem;"><strong style="box-sizing: border-box;font-weight: 600;color: rgb(51, 51, 51);"><span leaf="">安全建议</span></strong> <section> <span leaf="">:妥善保护私钥文件,不得泄露给使用者。</span> </section></li> </ul> <h3 data-sourcepos="200:1-200:56" style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1rem;font-weight: 600;line-height: 1.25;font-size: 1.25rem;color: rgb(5, 149, 191);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-style: normal;font-variant-caps: normal;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span style="box-sizing: border-box;display: inline-block;fill: currentcolor;vertical-align: middle;color: rgb(5, 149, 191);visibility: hidden;"></span><span leaf="">基于 TrueLicense 的 License 验证与安装优化</span></h3> <p data-sourcepos="202:1-202:169" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-size: 16px;font-style: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span leaf="">本文将详细介绍如何在项目中通过 TrueLicense 实现 License 的验证与安装。以下优化后的代码和配置旨在满足不同使用场景的需求。</span></p> <h4 data-sourcepos="204:1-204:34" style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1rem;font-weight: 600;line-height: 1.25;font-size: 16px;color: rgb(5, 149, 191);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-style: normal;font-variant-caps: normal;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span style="box-sizing: border-box;display: inline-block;fill: currentcolor;vertical-align: middle;color: rgb(5, 149, 191);visibility: hidden;"></span><span leaf="">使用者的</span><span leaf=""> </span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, monospace;font-size: 13.6px;padding: 0.2rem 0.4rem;margin: 0px;background-color: rgb(247, 248, 248);color: rgb(9, 132, 79);border-radius: 0.1875rem;><span leaf="">pom.xml</span></code><span leaf=""> </span><span leaf="">配置</span></h4> <pre data-sourcepos="205:1-212:3" tabindex="0" style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;margin: 0.5rem 0px;overflow-wrap: normal;padding: 1rem;overflow: auto;line-height: 1.45;background: rgb(247, 248, 248);border-radius: 0.1875rem;color: black;text-align: left;word-spacing: normal;word-break: normal;tab-size: 4;hyphens: none;><code style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;padding: 0px;margin: 0px;background-color: initial;color: rgb(9, 132, 79);border-radius: 0.1875rem;background-image: none;background-position: 0% 0%;background-size: auto;background-repeat: repeat;background-attachment: scroll;background-origin: padding-box;background-clip: border-box;text-align: left;word-spacing: normal;word-break: normal;overflow-wrap: normal;tab-size: 4;hyphens: none;border: 0px;display: inline;overflow: visible;line-height: inherit;><span style="box-sizing: border-box;color: rgb(142, 156, 146);"><span leaf=""><!-- License --></span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf=""><</span></span><span leaf="">dependency</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">></span></span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf=""><</span></span><span leaf="">groupId</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">></span></span></span><span leaf="">de.schlichtherle.truelicense</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf=""><!--/</span--></span><span leaf="">groupId</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">></span></span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf=""><</span></span><span leaf="">artifactId</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">></span></span></span><span leaf="">truelicense-core</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf=""><!--/</span--></span><span leaf="">artifactId</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">></span></span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf=""><</span></span><span leaf="">version</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">></span></span></span><span leaf="">1.33</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf=""><!--/</span--></span><span leaf="">version</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">></span></span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf=""><!--/</span--></span><span leaf="">dependency</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">></span></span></span><span leaf=""><br></span></span></span></span></span></code></pre> <h4 data-sourcepos="214:1-214:22" style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1rem;font-weight: 600;line-height: 1.25;font-size: 16px;color: rgb(5, 149, 191);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-style: normal;font-variant-caps: normal;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span style="box-sizing: border-box;display: inline-block;fill: currentcolor;vertical-align: middle;color: rgb(5, 149, 191);visibility: hidden;"></span><span leaf="">License 校验类</span></h4> <p data-sourcepos="215:1-215:51" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-size: 16px;font-style: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span leaf="">创建</span><span leaf=""> </span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, monospace;font-size: 13.6px;padding: 0.2rem 0.4rem;margin: 0px;background-color: rgb(247, 248, 248);color: rgb(9, 132, 79);border-radius: 0.1875rem;><span leaf="">com.icoderoad.license.LicenseVerify</span></code><span leaf=""> </span><span leaf="">类:</span></p> <pre data-sourcepos="217:1-279:3" tabindex="0" style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;margin: 0.5rem 0px;overflow-wrap: normal;padding: 1rem;overflow: auto;line-height: 1.45;background: rgb(247, 248, 248);border-radius: 0.1875rem;color: black;text-align: left;word-spacing: normal;word-break: normal;tab-size: 4;hyphens: none;><code style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;padding: 0px;margin: 0px;background-color: initial;color: rgb(9, 132, 79);border-radius: 0.1875rem;background-image: none;background-position: 0% 0%;background-size: auto;background-repeat: repeat;background-attachment: scroll;background-origin: padding-box;background-clip: border-box;text-align: left;word-spacing: normal;word-break: normal;overflow-wrap: normal;tab-size: 4;hyphens: none;border: 0px;display: inline;overflow: visible;line-height: inherit;><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">package</span></span><span leaf=""> </span><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">com</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">icoderoad</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">license</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">de</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">schlichtherle</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">license</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;"><span leaf="">*</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">lombok</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Data</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">lombok</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">extern</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">slf4j</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Slf4j</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">java</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">io</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">File</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">java</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">text</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">DateFormat</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">java</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">text</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">MessageFormat</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">java</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">text</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">SimpleDateFormat</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">java</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">util</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">prefs</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Preferences</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Slf4j</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">class</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseVerify</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(142, 156, 146);"><span leaf="">// 安装 License 证书</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">synchronized</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseContent</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">install</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseVerifyParam</span></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseContent</span></span><span leaf=""> result </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">null</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">DateFormat</span></span><span leaf=""> format </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">SimpleDateFormat</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"yyyy-MM-dd HH:mm:ss"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">try</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseManager</span></span><span leaf=""> licenseManager </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseManagerHolder</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getInstance</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">initLicenseParam</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> licenseManager</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">uninstall</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> result </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span leaf=""> licenseManager</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">install</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">File</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getLicensePath</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> log</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">info</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">MessageFormat</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">format</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"证书安装成功,证书有效期:{0} - {1}"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""><br></span><span leaf=""> format</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">format</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">result</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getNotBefore</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""> format</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">format</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">result</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getNotAfter</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">catch</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Exception</span></span><span leaf=""> e</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> log</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">error</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"证书安装失败: {}"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""> e</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getMessage</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">return</span></span><span leaf=""> result</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(142, 156, 146);"><span leaf="">// 校验 License 证书</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">boolean</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">verify</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseManager</span></span><span leaf=""> licenseManager </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseManagerHolder</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getInstance</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">null</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">DateFormat</span></span><span leaf=""> format </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">SimpleDateFormat</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"yyyy-MM-dd HH:mm:ss"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">try</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseContent</span></span><span leaf=""> licenseContent </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span leaf=""> licenseManager</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">verify</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> log</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">info</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">MessageFormat</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">format</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"证书校验通过,证书有效期:{0} - {1}"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""><br></span><span leaf=""> format</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">format</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">licenseContent</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getNotBefore</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""> format</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">format</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">licenseContent</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getNotAfter</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">return</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">true</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">catch</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Exception</span></span><span leaf=""> e</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> log</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">error</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"证书校验失败: {}"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""> e</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getMessage</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">return</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">false</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(142, 156, 146);"><span leaf="">// 初始化证书生成参数</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseParam</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">initLicenseParam</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseVerifyParam</span></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Preferences</span></span><span leaf=""> preferences </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Preferences</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">userNodeForPackage</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseVerify</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">class</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">CipherParam</span></span><span leaf=""> cipherParam </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">DefaultCipherParam</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getStorePass</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">KeyStoreParam</span></span><span leaf=""> publicStoreParam </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">CustomKeyStoreParam</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseVerify</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">class</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getPublicKeysStorePath</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getPublicAlias</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getStorePass</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">null</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">return</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">DefaultLicenseParam</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getSubject</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""> preferences</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""> publicStoreParam</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""> cipherParam</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span></code></pre> <h4 data-sourcepos="281:1-281:37" style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1rem;font-weight: 600;line-height: 1.25;font-size: 16px;color: rgb(5, 149, 191);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-style: normal;font-variant-caps: normal;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span style="box-sizing: border-box;display: inline-block;fill: currentcolor;vertical-align: middle;color: rgb(5, 149, 191);visibility: hidden;"></span><span leaf="">License 校验类需要的参数</span></h4> <pre data-sourcepos="283:1-294:3" tabindex="0" style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;margin: 0.5rem 0px;overflow-wrap: normal;padding: 1rem;overflow: auto;line-height: 1.45;background: rgb(247, 248, 248);border-radius: 0.1875rem;color: black;text-align: left;word-spacing: normal;word-break: normal;tab-size: 4;hyphens: none;><code style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;padding: 0px;margin: 0px;background-color: initial;color: rgb(9, 132, 79);border-radius: 0.1875rem;background-image: none;background-position: 0% 0%;background-size: auto;background-repeat: repeat;background-attachment: scroll;background-origin: padding-box;background-clip: border-box;text-align: left;word-spacing: normal;word-break: normal;overflow-wrap: normal;tab-size: 4;hyphens: none;border: 0px;display: inline;overflow: visible;line-height: inherit;><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">package</span></span><span leaf=""> </span><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">com</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">icoderoad</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">license</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Data</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">class</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseVerifyParam</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> subject</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> publicAlias</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> storePass</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> licensePath</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> publicKeysStorePath</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span></code></pre> <h4 data-sourcepos="296:1-296:30" style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1rem;font-weight: 600;line-height: 1.25;font-size: 16px;color: rgb(5, 149, 191);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-style: normal;font-variant-caps: normal;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span style="box-sizing: border-box;display: inline-block;fill: currentcolor;vertical-align: middle;color: rgb(5, 149, 191);visibility: hidden;"></span><span leaf="">自定义</span><span leaf=""> </span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, monospace;font-size: 13.6px;padding: 0.2rem 0.4rem;margin: 0px;background-color: rgb(247, 248, 248);color: rgb(9, 132, 79);border-radius: 0.1875rem;><span leaf="">KeyStoreParam</span></code></h4> <pre data-sourcepos="298:1-342:3" tabindex="0" style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;margin: 0.5rem 0px;overflow-wrap: normal;padding: 1rem;overflow: auto;line-height: 1.45;background: rgb(247, 248, 248);border-radius: 0.1875rem;color: black;text-align: left;word-spacing: normal;word-break: normal;tab-size: 4;hyphens: none;><code style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;padding: 0px;margin: 0px;background-color: initial;color: rgb(9, 132, 79);border-radius: 0.1875rem;background-image: none;background-position: 0% 0%;background-size: auto;background-repeat: repeat;background-attachment: scroll;background-origin: padding-box;background-clip: border-box;text-align: left;word-spacing: normal;word-break: normal;overflow-wrap: normal;tab-size: 4;hyphens: none;border: 0px;display: inline;overflow: visible;line-height: inherit;><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">package</span></span><span leaf=""> </span><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">com</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">icoderoad</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">license</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">de</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">schlichtherle</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">license</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">AbstractKeyStoreParam</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">java</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">io</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">IOException</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">java</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">io</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">InputStream</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">java</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">nio</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">file</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Files</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">java</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">nio</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">file</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Paths</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">class</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">CustomKeyStoreParam</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">extends</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">AbstractKeyStoreParam</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">final</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> storePath</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">final</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> alias</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">final</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> storePwd</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">final</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> keyPwd</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">CustomKeyStoreParam</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Class</span></span><span leaf=""> clazz</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> resource</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> alias</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> storePwd</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> keyPwd</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">super</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">clazz</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""> resource</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">this</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">storePath </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span leaf=""> resource</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">this</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">alias </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span leaf=""> alias</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">this</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">storePwd </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span leaf=""> storePwd</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">this</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">keyPwd </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span leaf=""> keyPwd</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Override</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getAlias</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">return</span></span><span leaf=""> alias</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Override</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getStorePwd</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">return</span></span><span leaf=""> storePwd</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Override</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getKeyPwd</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">return</span></span><span leaf=""> keyPwd</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Override</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">InputStream</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getStream</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">throws</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">IOException</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">return</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Files</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">newInputStream</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Paths</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">get</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">storePath</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span></code></pre> <h4 data-sourcepos="344:1-344:29" style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1rem;font-weight: 600;line-height: 1.25;font-size: 16px;color: rgb(5, 149, 191);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-style: normal;font-variant-caps: normal;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span style="box-sizing: border-box;display: inline-block;fill: currentcolor;vertical-align: middle;color: rgb(5, 149, 191);visibility: hidden;"></span><span leaf="">LicenseManager 的单例</span></h4> <pre data-sourcepos="346:1-366:3" tabindex="0" style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;margin: 0.5rem 0px;overflow-wrap: normal;padding: 1rem;overflow: auto;line-height: 1.45;background: rgb(247, 248, 248);border-radius: 0.1875rem;color: black;text-align: left;word-spacing: normal;word-break: normal;tab-size: 4;hyphens: none;><code style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;padding: 0px;margin: 0px;background-color: initial;color: rgb(9, 132, 79);border-radius: 0.1875rem;background-image: none;background-position: 0% 0%;background-size: auto;background-repeat: repeat;background-attachment: scroll;background-origin: padding-box;background-clip: border-box;text-align: left;word-spacing: normal;word-break: normal;overflow-wrap: normal;tab-size: 4;hyphens: none;border: 0px;display: inline;overflow: visible;line-height: inherit;><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">package</span></span><span leaf=""> </span><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">com</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">icoderoad</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">license</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">de</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">schlichtherle</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">license</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseManager</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">de</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">schlichtherle</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">license</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseParam</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">class</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseManagerHolder</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">static</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">volatile</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseManager</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">LICENSE_MANAGER</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">static</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseManager</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getInstance</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseParam</span></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">if</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">LICENSE_MANAGER</span></span><span style="box-sizing: border-box;"><span leaf="">==</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">null</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">synchronized</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseManagerHolder</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">class</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">if</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">LICENSE_MANAGER</span></span><span style="box-sizing: border-box;"><span leaf="">==</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">null</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">LICENSE_MANAGER</span></span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseManager</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">return</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">LICENSE_MANAGER</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span></code></pre> <h4 data-sourcepos="368:1-368:32" style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1rem;font-weight: 600;line-height: 1.25;font-size: 16px;color: rgb(5, 149, 191);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-style: normal;font-variant-caps: normal;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span style="box-sizing: border-box;display: inline-block;fill: currentcolor;vertical-align: middle;color: rgb(5, 149, 191);visibility: hidden;"></span><span leaf="">项目启动时安装证书</span></h4> <h5 data-sourcepos="369:1-369:37" style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1rem;font-weight: 600;line-height: 1.25;font-size: 0.875rem;color: rgb(5, 149, 191);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-style: normal;font-variant-caps: normal;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span style="box-sizing: border-box;display: inline-block;fill: currentcolor;vertical-align: middle;color: rgb(5, 149, 191);visibility: hidden;"></span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, monospace;font-size: 11.9px;padding: 0.2rem 0.4rem;margin: 0px;background-color: rgb(247, 248, 248);color: rgb(9, 132, 79);border-radius: 0.1875rem;><span leaf="">application.properties</span></code><span leaf=""> </span><span leaf="">配置</span></h5> <pre data-sourcepos="370:1-375:3" tabindex="0" style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;margin: 0.5rem 0px;overflow-wrap: normal;padding: 1rem;overflow: auto;line-height: 1.45;background: rgb(247, 248, 248);border-radius: 0.1875rem;color: black;text-align: left;word-spacing: normal;word-break: normal;tab-size: 4;hyphens: none;><code style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;padding: 0px;margin: 0px;background-color: initial;color: rgb(9, 132, 79);border-radius: 0.1875rem;background-image: none;background-position: 0% 0%;background-size: auto;background-repeat: repeat;background-attachment: scroll;background-origin: padding-box;background-clip: border-box;text-align: left;word-spacing: normal;word-break: normal;overflow-wrap: normal;tab-size: 4;hyphens: none;border: 0px;display: inline;overflow: visible;line-height: inherit;><span style="box-sizing: border-box;color: rgb(142, 156, 146);"><span leaf=""># License 配置</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">license.subject</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">license</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">license.publicAlias</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">myKeyPass123</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">license.storePass</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">myStorePass123</span></span><span leaf=""><br></span></code></pre> <h5 data-sourcepos="377:1-377:30" style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1rem;font-weight: 600;line-height: 1.25;font-size: 0.875rem;color: rgb(5, 149, 191);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-style: normal;font-variant-caps: normal;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span style="box-sizing: border-box;display: inline-block;fill: currentcolor;vertical-align: middle;color: rgb(5, 149, 191);visibility: hidden;"></span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, monospace;font-size: 11.9px;padding: 0.2rem 0.4rem;margin: 0px;background-color: rgb(247, 248, 248);color: rgb(9, 132, 79);border-radius: 0.1875rem;><span leaf="">LicenseCheckRunner</span></code><span leaf=""> </span><span leaf="">类</span></h5> <pre data-sourcepos="379:1-418:3" tabindex="0" style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;margin: 0.5rem 0px;overflow-wrap: normal;padding: 1rem;overflow: auto;line-height: 1.45;background: rgb(247, 248, 248);border-radius: 0.1875rem;color: black;text-align: left;word-spacing: normal;word-break: normal;tab-size: 4;hyphens: none;><code style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;padding: 0px;margin: 0px;background-color: initial;color: rgb(9, 132, 79);border-radius: 0.1875rem;background-image: none;background-position: 0% 0%;background-size: auto;background-repeat: repeat;background-attachment: scroll;background-origin: padding-box;background-clip: border-box;text-align: left;word-spacing: normal;word-break: normal;overflow-wrap: normal;tab-size: 4;hyphens: none;border: 0px;display: inline;overflow: visible;line-height: inherit;><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">package</span></span><span leaf=""> </span><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">com</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">icoderoad</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">license</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">lombok</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">extern</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">slf4j</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Slf4j</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">org</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">springframework</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">beans</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">factory</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">annotation</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Value</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">org</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">springframework</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">boot</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">ApplicationArguments</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">org</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">springframework</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">boot</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">ApplicationRunner</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">org</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">springframework</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">stereotype</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Component</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Slf4j</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Component</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">class</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseCheckRunner</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">implements</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">ApplicationRunner</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Value</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"${license.subject}"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> subject</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Value</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"${license.publicAlias}"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> publicAlias</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Value</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"${license.storePass}"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">private</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> storePass</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Override</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">void</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">run</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">ApplicationArguments</span></span><span leaf=""> args</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">throws</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Exception</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> log</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">info</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"++++++++ 开始安装证书 ++++++++"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseVerifyParam</span></span><span leaf=""> param </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseVerifyParam</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setSubject</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">subject</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setPublicAlias</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">publicAlias</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setStorePass</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">storePass</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span leaf=""> resourcePath </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getClass</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getClassLoader</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getResource</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">""</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getPath</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setLicensePath</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">resourcePath </span><span style="box-sizing: border-box;"><span leaf="">+</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"license.lic"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setPublicKeysStorePath</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">resourcePath </span><span style="box-sizing: border-box;"><span leaf="">+</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"publicCerts.keystore"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseVerify</span></span><span leaf=""> licenseVerify </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseVerify</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> licenseVerify</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">install</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">param</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> log</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">info</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"++++++++ 证书安装结束 ++++++++"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span></code></pre> <h4 data-sourcepos="420:1-420:20" style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1rem;font-weight: 600;line-height: 1.25;font-size: 16px;color: rgb(5, 149, 191);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-style: normal;font-variant-caps: normal;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span style="box-sizing: border-box;display: inline-block;fill: currentcolor;vertical-align: middle;color: rgb(5, 149, 191);visibility: hidden;"></span><span leaf="">配置拦截器</span></h4> <h5 data-sourcepos="421:1-421:31" style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1rem;font-weight: 600;line-height: 1.25;font-size: 0.875rem;color: rgb(5, 149, 191);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-style: normal;font-variant-caps: normal;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span style="box-sizing: border-box;display: inline-block;fill: currentcolor;vertical-align: middle;color: rgb(5, 149, 191);visibility: hidden;"></span><code style="box-sizing: border-box;font-family: SFMono-Regular, Consolas, " liberation mono, menlo, monospace;font-size: 11.9px;padding: 0.2rem 0.4rem;margin: 0px;background-color: rgb(247, 248, 248);color: rgb(9, 132, 79);border-radius: 0.1875rem;><span leaf="">LicenseCheckInterceptor</span></code></h5> <pre data-sourcepos="423:1-453:3" tabindex="0" style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;margin: 0.5rem 0px;overflow-wrap: normal;padding: 1rem;overflow: auto;line-height: 1.45;background: rgb(247, 248, 248);border-radius: 0.1875rem;color: black;text-align: left;word-spacing: normal;word-break: normal;tab-size: 4;hyphens: none;><code style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;padding: 0px;margin: 0px;background-color: initial;color: rgb(9, 132, 79);border-radius: 0.1875rem;background-image: none;background-position: 0% 0%;background-size: auto;background-repeat: repeat;background-attachment: scroll;background-origin: padding-box;background-clip: border-box;text-align: left;word-spacing: normal;word-break: normal;overflow-wrap: normal;tab-size: 4;hyphens: none;border: 0px;display: inline;overflow: visible;line-height: inherit;><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">package</span></span><span leaf=""> </span><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">com</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">icoderoad</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">interceptor</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">com</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">icoderoad</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">license</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseVerify</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">lombok</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">extern</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">slf4j</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Slf4j</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">org</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">springframework</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">web</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">servlet</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">HandlerInterceptor</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">javax</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">servlet</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">http</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">HttpServletRequest</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">javax</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">servlet</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">http</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">HttpServletResponse</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">java</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">util</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">HashMap</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">java</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">util</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Map</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Slf4j</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">class</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseCheckInterceptor</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">implements</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">HandlerInterceptor</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Override</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">boolean</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">preHandle</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">HttpServletRequest</span></span><span leaf=""> request</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">HttpServletResponse</span></span><span leaf=""> response</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Object</span></span><span leaf=""> handler</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">throws</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Exception</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseVerify</span></span><span leaf=""> licenseVerify </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseVerify</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">boolean</span></span><span leaf=""> verifyResult </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span leaf=""> licenseVerify</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">verify</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">if</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">verifyResult</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">return</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">true</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">else</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> response</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">setCharacterEncoding</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"utf-8"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Map</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf=""><</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">String</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">></span></span></span><span leaf=""> result </span><span style="box-sizing: border-box;"><span leaf="">=</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">HashMap</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf=""><</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">></span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">1</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> result</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">put</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"result"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">,</span></span><span style="box-sizing: border-box;color: rgb(211, 45, 38);"><span leaf="">"您的证书无效,请核查服务器是否取得授权或重新申请证书!"</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> response</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">getWriter</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">write</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">JSON</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">toJSONString</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span leaf="">result</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">return</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">false</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span></code></pre> <h5 data-sourcepos="455:1-455:21" style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1rem;font-weight: 600;line-height: 1.25;font-size: 0.875rem;color: rgb(5, 149, 191);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-style: normal;font-variant-caps: normal;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span style="box-sizing: border-box;display: inline-block;fill: currentcolor;vertical-align: middle;color: rgb(5, 149, 191);visibility: hidden;"></span><span leaf="">注册拦截器</span></h5> <pre data-sourcepos="457:1-472:3" tabindex="0" style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;margin: 0.5rem 0px;overflow-wrap: normal;padding: 1rem;overflow: auto;line-height: 1.45;background: rgb(247, 248, 248);border-radius: 0.1875rem;color: black;text-align: left;word-spacing: normal;word-break: normal;tab-size: 4;hyphens: none;><code style="white-space:pre-wrap;box-sizing: border-box;font-family: Consolas, Monaco, " andale mono, ubuntu monospace;font-size: 13.6px;padding: 0px;margin: 0px;background-color: initial;color: rgb(9, 132, 79);border-radius: 0.1875rem;background-image: none;background-position: 0% 0%;background-size: auto;background-repeat: repeat;background-attachment: scroll;background-origin: padding-box;background-clip: border-box;text-align: left;word-spacing: normal;word-break: normal;overflow-wrap: normal;tab-size: 4;hyphens: none;border: 0px;display: inline;overflow: visible;line-height: inherit;><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">package</span></span><span leaf=""> </span><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">com</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">icoderoad</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">config</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">com</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">icoderoad</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">interceptor</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseCheckInterceptor</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">org</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">springframework</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">context</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">annotation</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">Configuration</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">org</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">springframework</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">web</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">servlet</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">config</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">annotation</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">InterceptorRegistry</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">import</span></span><span style="box-sizing: border-box;"><span style="box-sizing: border-box;opacity: 0.7;"><span leaf="">org</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">springframework</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">web</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">servlet</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">config</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span leaf="">annotation</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">WebMvcConfigurer</span></span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Configuration</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">class</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">WebMvcConfig</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">implements</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">WebMvcConfigurer</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">@Override</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">public</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">void</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">addInterceptors</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">InterceptorRegistry</span></span><span leaf=""> registry</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">{</span></span><span leaf=""><br></span><span leaf=""> registry</span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">.</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">addInterceptor</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(188, 49, 156);"><span leaf="">new</span></span><span style="box-sizing: border-box;color: rgb(150, 125, 65);"><span leaf="">LicenseCheckInterceptor</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">(</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">)</span></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">;</span></span><span leaf=""><br></span><span leaf=""> </span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span><span style="box-sizing: border-box;color: rgb(40, 52, 206);"><span leaf="">}</span></span><span leaf=""><br></span></code></pre> <h3 data-sourcepos="474:1-474:10" style="box-sizing: border-box;margin-top: 1.5rem;margin-bottom: 1rem;font-weight: 600;line-height: 1.25;font-size: 1.25rem;color: rgb(5, 149, 191);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-style: normal;font-variant-caps: normal;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span style="box-sizing: border-box;display: inline-block;fill: currentcolor;vertical-align: middle;color: rgb(5, 149, 191);visibility: hidden;"></span><span leaf="">总结</span></h3> <p data-sourcepos="476:1-476:223" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 1rem;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-size: 16px;font-style: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span leaf="">本文系统性地阐述了在</span><span leaf=""> </span><strong style="box-sizing: border-box;font-weight: 600;color: rgb(51, 51, 51);"><span leaf="">SpringBoot</span></strong><span leaf=""> </span><span leaf="">项目中实现 License 认证的简洁方案。从背景概述到实现细节,我们深入探讨了如何通过生成密钥对和证书实现高效的 License 校验机制。</span></p> <p data-sourcepos="478:1-479:300" style="box-sizing: border-box;margin-top: 0px;margin-bottom: 0px !important;caret-color: rgb(51, 51, 51);color: rgb(51, 51, 51);font-family: -apple-system, BlinkMacSystemFont, " segoe ui, helvetica, arial, sans-serif, apple color emoji, segoe ui emoji;font-size: 16px;font-style: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: auto;text-align: start;text-indent: 0px;text-transform: none;white-space: normal;widows: auto;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration: none;><span leaf="">通过使用</span><span leaf=""> </span><strong style="box-sizing: border-box;font-weight: 600;color: rgb(51, 51, 51);"><span leaf="">TrueLicense</span></strong><span leaf=""> </span><span leaf="">工具,开发者能够快速生成符合项目需求的证书,而在项目中引入 License 验证功能后,可以有效提升应用的安全性和合规性。此外,本文所介绍的方案灵活性强,适用于多种使用场景,尤其是在复杂的企业内网部署环境中具有显著优势。</span><span leaf=""><br></span><span leaf="">未来,您可以根据项目的特定需求,进一步扩展 License 认证功能,例如:绑定硬件信息、增加多级权限控制等,以实现更加精细化的授权管理。希望本篇文章能够为您提供切实可行的技术思路,助力构建专业的 License 认证体系。</span></p>
作者:微信小助手
<p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));margin: 0px;color: rgb(10, 10, 10);font-family: ui-sans-serif, system-ui, sans-serif, " apple color emoji, segoe ui symbol, noto emoji;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 0px;line-height: 0;><span leaf=""> </span></p> <section style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(10, 10, 10);font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));margin: 1.5em 8px;text-align: justify;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">在 Java 8 引入的函数式编程支持中,</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, " liberation mono, courier new, monospace;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Function</span></code><span leaf=""> 接口作为最常用的工具之一,广泛应用于各种复杂的场景。今天我们将继续探讨 GitHub 上一些非常厉害的 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Function</span></code><span leaf=""> 代码写法参考,这些代码在实际项目中解决了各种问题,并展示了 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Function</span></code><span leaf=""> 的高级技巧。我们将看到一些新的实践,远离前面提到的简单示例,而是探索更具创意和挑战性的应用。</span></p> <hr style="box-sizing: border-box;border: none;height: 1px;color: inherit;margin: 2em 0px;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, microsoft yahei, arial, sans-serif;font-size: 15px;transform-origin: 0px 0px;transform: scale(1, 0.5);background: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0));> <h3 style="box-sizing: border-box;border-width: 0px 0px 1px 4px;border-style: solid solid dashed;border-bottom-color: rgb(0, 152, 116);border-left-color: rgb(0, 152, 116);font-size: 18px;font-weight: bold;margin: 2em 8px 0.75em 0px;text-align: left;line-height: 1.2;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;padding-left: 12px;color: rgb(63, 63, 63);><span leaf="">1. </span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-weight: bold;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: inherit;color: rgb(0, 152, 116);><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 16.2px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Function</span></code><span leaf=""> 和 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 16.2px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Optional</span></code><span leaf=""> 配合使用</span></strong></h3> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));margin: 1.5em 8px;text-align: justify;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">在很多实际开发中,</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Optional</span></code><span leaf=""> 用于避免空指针异常(</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">NullPointerException</span></code><span leaf="">)。将 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Function</span></code><span leaf=""> 与 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Optional</span></code><span leaf=""> 配合使用可以帮助我们优雅地处理可空对象,并避免冗长的条件判断。</span></p> <h4 style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-size: 16.5px;font-weight: bold;margin: 2em 8px 0.5em;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(0, 152, 116);><span leaf="">代码示例:</span></h4> <pre style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14px;margin: 10px 8px;color: rgb(171, 178, 191);background: rgb(40, 44, 52);text-align: left;line-height: 1.5;overflow-x: auto;border-radius: 8px;box-shadow: rgba(0, 0, 0.05) 0px inset;padding: !important;><span hidden style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));display: flex;padding: 10px 14px 0px;"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" width="45px" height="13px" viewbox="0 0 450 130"> <ellipse cx="50" cy="65" rx="50" ry="52" stroke="rgb(220,60,54)" stroke-width="2" fill="rgb(237,108,96)"></ellipse><ellipse cx="225" cy="65" rx="50" ry="52" stroke="rgb(218,151,33)" stroke-width="2" fill="rgb(247,193,81)"></ellipse><ellipse cx="400" cy="65" rx="50" ry="52" stroke="rgb(27,161,37)" stroke-width="2" fill="rgb(100,200,86)"></ellipse> </svg></span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: " fira code, menlo, operator mono, consolas, monaco, monospace;font-feature-settings: normal;font-variation-settings: normal;font-size: 15px;display: -webkit-box;padding: 0.5em 1em 1em;overflow-x: auto;text-indent: 0px;text-align: left;line-height: 1.75;margin: 0px;white-space: pre-wrap;><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">import</span></span><span leaf=""> java.util.Optional;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">import</span></span><span leaf=""> java.util.function.Function;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">public</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">class</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(230, 192, 123);"><span leaf="">FunctionWithOptional</span></span><span leaf=""> {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">public</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">static</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">void</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(97, 174, 238);"><span leaf="">main</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf="">(String[] args)</span></span><span leaf=""> {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 定义一个 User 类</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">class</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(230, 192, 123);"><span leaf="">User</span></span><span leaf=""> {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> String name;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">int</span></span><span leaf=""> age;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> User(String name, </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">int</span></span><span leaf=""> age) {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(230, 192, 123);"><span leaf="">this</span></span><span leaf="">.name = name;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(230, 192, 123);"><span leaf="">this</span></span><span leaf="">.age = age;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> }</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> }</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 使用 Optional 和 Function 提取用户年龄</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> Function <user, optional<integer>> getAge = user -> Optional.ofNullable(user).map(u -> u.age); </user,></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 创建一个 User 对象</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">User</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">user</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">=</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">new</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(230, 192, 123);"><span leaf="">User</span></span><span leaf="">(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"Alice"</span></span><span leaf="">, </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">30</span></span><span leaf="">);</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 使用 Optional 来安全地获取年龄</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> Optional <integer> age = getAge.apply(user); </integer></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> age.ifPresent(a -> System.out.println(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"User's age: "</span></span><span leaf=""> + a)); </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 输出 User's age: 30</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 使用 null 时,返回空 Optional</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> age = getAge.apply(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(86, 182, 194);"><span leaf="">null</span></span><span leaf="">);</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> age.ifPresent(a -> System.out.println(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"User's age: "</span></span><span leaf=""> + a)); </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 不输出任何内容</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> }</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf="">}</span></code></pre> <h4 style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-size: 16.5px;font-weight: bold;margin: 2em 8px 0.5em;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(0, 152, 116);><span leaf="">解释:</span></h4> <ul style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));list-style: none;margin: 0px;padding: 0px 0px 0px 1.5em;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;color: rgb(63, 63, 63); class="list-paddingleft-1"> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">getAge</span></code><span leaf=""> 是一个 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Function</span></code><span leaf="">,它接收 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">User</span></code><span leaf=""> 对象,并使用 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Optional</span></code><span leaf=""> 包装返回的结果。这样可以优雅地处理空值情况,避免了手动检查 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">null</span></code><span leaf="">。</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• 通过 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">map()</span></code><span leaf=""> 方法,只有在 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">user</span></code><span leaf=""> 非 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">null</span></code><span leaf=""> 时才会提取 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">age</span></code><span leaf="">,否则返回 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Optional.empty()</span></code><span leaf="">,避免了异常的发生。</span> </section></li> </ul> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));margin: 1.5em 8px;text-align: justify;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">这种方式在链式调用中非常有用,可以高效地避免 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">NullPointerException</span></code><span leaf="">。</span></p> <hr style="box-sizing: border-box;border: none;height: 1px;color: inherit;margin: 2em 0px;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, microsoft yahei, arial, sans-serif;font-size: 15px;transform-origin: 0px 0px;transform: scale(1, 0.5);background: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0));> <h2 style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-size: 19.5px;font-weight: bold;margin: 4em auto 2em;text-align: center;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;display: table;padding: 0.3em 1em;color: rgb(255, 255, 255);background: rgb(0, 152, 116);border-radius: 8px;box-shadow: rgba(0, 0, 0.1) 0px 4px 6px;><span leaf="">2. </span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-weight: bold;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: inherit;color: rgb(0, 152, 116);><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 17.55px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Function</span></code><span leaf=""> 和 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 17.55px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Predicate</span></code><span leaf=""> 联合使用进行过滤</span></strong></h2> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));margin: 1.5em 8px;text-align: justify;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">在处理数据集合时,我们经常需要对数据进行过滤并进行转换,使用 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Function</span></code><span leaf=""> 和 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Predicate</span></code><span leaf=""> 联合能够简洁地实现这一功能。例如,可以先使用 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Predicate</span></code><span leaf=""> 筛选符合条件的数据,再使用 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Function</span></code><span leaf=""> 转换数据的形式。</span></p> <h4 style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-size: 16.5px;font-weight: bold;margin: 2em 8px 0.5em;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(0, 152, 116);><span leaf="">代码示例:</span></h4> <pre style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14px;margin: 10px 8px;color: rgb(171, 178, 191);background: rgb(40, 44, 52);text-align: left;line-height: 1.5;overflow-x: auto;border-radius: 8px;box-shadow: rgba(0, 0, 0.05) 0px inset;padding: !important;><span hidden style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));display: flex;padding: 10px 14px 0px;"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" width="45px" height="13px" viewbox="0 0 450 130"> <ellipse cx="50" cy="65" rx="50" ry="52" stroke="rgb(220,60,54)" stroke-width="2" fill="rgb(237,108,96)"></ellipse><ellipse cx="225" cy="65" rx="50" ry="52" stroke="rgb(218,151,33)" stroke-width="2" fill="rgb(247,193,81)"></ellipse><ellipse cx="400" cy="65" rx="50" ry="52" stroke="rgb(27,161,37)" stroke-width="2" fill="rgb(100,200,86)"></ellipse> </svg></span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: " fira code, menlo, operator mono, consolas, monaco, monospace;font-feature-settings: normal;font-variation-settings: normal;font-size: 15px;display: -webkit-box;padding: 0.5em 1em 1em;overflow-x: auto;text-indent: 0px;text-align: left;line-height: 1.75;margin: 0px;white-space: pre-wrap;><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">import</span></span><span leaf=""> java.util.List;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">import</span></span><span leaf=""> java.util.function.Function;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">import</span></span><span leaf=""> java.util.function.Predicate;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">import</span></span><span leaf=""> java.util.stream.Collectors;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">public</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">class</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(230, 192, 123);"><span leaf="">FunctionWithPredicate</span></span><span leaf=""> {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">public</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">static</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">void</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(97, 174, 238);"><span leaf="">main</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf="">(String[] args)</span></span><span leaf=""> {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 假设我们有一个 User 类</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">class</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(230, 192, 123);"><span leaf="">User</span></span><span leaf=""> {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> String name;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">int</span></span><span leaf=""> age;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> User(String name, </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">int</span></span><span leaf=""> age) {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(230, 192, 123);"><span leaf="">this</span></span><span leaf="">.name = name;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(230, 192, 123);"><span leaf="">this</span></span><span leaf="">.age = age;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> }</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(97, 174, 238);"><span leaf="">@Override</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">public</span></span><span leaf=""> String </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(97, 174, 238);"><span leaf="">toString</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf="">()</span></span><span leaf=""> {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">return</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"User{name='"</span></span><span leaf=""> + name + </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"', age="</span></span><span leaf=""> + age + </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"}"</span></span><span leaf="">;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> }</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> }</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 创建一组 User 数据</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> List <user> users = List.of( </user></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">new</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(230, 192, 123);"><span leaf="">User</span></span><span leaf="">(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"Alice"</span></span><span leaf="">, </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">25</span></span><span leaf="">),</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">new</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(230, 192, 123);"><span leaf="">User</span></span><span leaf="">(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"Bob"</span></span><span leaf="">, </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">35</span></span><span leaf="">),</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">new</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(230, 192, 123);"><span leaf="">User</span></span><span leaf="">(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"Charlie"</span></span><span leaf="">, </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">28</span></span><span leaf="">),</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">new</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(230, 192, 123);"><span leaf="">User</span></span><span leaf="">(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"David"</span></span><span leaf="">, </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">40</span></span><span leaf="">)</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> );</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 定义一个 Predicate,筛选年龄大于 30 的用户</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> Predicate <user> isOlderThan30 = user -> user.age > </user></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">30</span></span><span leaf="">;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 定义一个 Function,提取用户的姓名</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> Function <user, string> getName = user -> user.name; </user,></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 筛选年龄大于 30 的用户并提取姓名</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> List <string> names = users.stream() </string></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> .filter(isOlderThan30) </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 使用 Predicate 进行筛选</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> .map(getName) </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 使用 Function 转换数据</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> .collect(Collectors.toList());</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> System.out.println(names); </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 输出 [Bob, David]</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> }</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf="">}</span></code></pre> <h4 style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-size: 16.5px;font-weight: bold;margin: 2em 8px 0.5em;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(0, 152, 116);><span leaf="">解释:</span></h4> <ul style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));list-style: none;margin: 0px;padding: 0px 0px 0px 1.5em;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;color: rgb(63, 63, 63); class="list-paddingleft-1"> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">isOlderThan30</span></code><span leaf=""> 是一个 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Predicate</span></code><span leaf="">,用于判断用户是否年纪大于 30。</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">getName</span></code><span leaf=""> 是一个 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Function</span></code><span leaf="">,将 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">User</span></code><span leaf=""> 对象转换为 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">String</span></code><span leaf=""> 类型(即用户的姓名)。</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• 通过 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">filter</span></code><span leaf=""> 和 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">map</span></code><span leaf=""> 的结合,我们能够高效地筛选出符合条件的用户,并转换成所需的数据格式。</span> </section></li> </ul> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));margin: 1.5em 8px;text-align: justify;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">这种方法让我们能够以更简洁的方式处理集合中的数据,避免了显式的 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">for</span></code><span leaf=""> 循环,提高了代码的可读性和可维护性。</span></p> <hr style="box-sizing: border-box;border: none;height: 1px;color: inherit;margin: 2em 0px;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, microsoft yahei, arial, sans-serif;font-size: 15px;transform-origin: 0px 0px;transform: scale(1, 0.5);background: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0));> <h3 style="box-sizing: border-box;border-width: 0px 0px 1px 4px;border-style: solid solid dashed;border-bottom-color: rgb(0, 152, 116);border-left-color: rgb(0, 152, 116);font-size: 18px;font-weight: bold;margin: 2em 8px 0.75em 0px;text-align: left;line-height: 1.2;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;padding-left: 12px;color: rgb(63, 63, 63);><span leaf="">3. </span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-weight: bold;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: inherit;color: rgb(0, 152, 116);><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 16.2px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Function</span></code><span leaf=""> 和 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 16.2px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Consumer</span></code><span leaf=""> 联合处理异步任务</span></strong></h3> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));margin: 1.5em 8px;text-align: justify;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">异步编程是现代应用中常见的模式,尤其是在处理 I/O 密集型任务时。</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Function</span></code><span leaf=""> 和 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Consumer</span></code><span leaf=""> 可以联合使用,用于处理异步回调中的数据流。</span></p> <h4 style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-size: 16.5px;font-weight: bold;margin: 2em 8px 0.5em;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(0, 152, 116);><span leaf="">代码示例:</span></h4> <pre style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14px;margin: 10px 8px;color: rgb(171, 178, 191);background: rgb(40, 44, 52);text-align: left;line-height: 1.5;overflow-x: auto;border-radius: 8px;box-shadow: rgba(0, 0, 0.05) 0px inset;padding: !important;><span hidden style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));display: flex;padding: 10px 14px 0px;"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" width="45px" height="13px" viewbox="0 0 450 130"> <ellipse cx="50" cy="65" rx="50" ry="52" stroke="rgb(220,60,54)" stroke-width="2" fill="rgb(237,108,96)"></ellipse><ellipse cx="225" cy="65" rx="50" ry="52" stroke="rgb(218,151,33)" stroke-width="2" fill="rgb(247,193,81)"></ellipse><ellipse cx="400" cy="65" rx="50" ry="52" stroke="rgb(27,161,37)" stroke-width="2" fill="rgb(100,200,86)"></ellipse> </svg></span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: " fira code, menlo, operator mono, consolas, monaco, monospace;font-feature-settings: normal;font-variation-settings: normal;font-size: 15px;display: -webkit-box;padding: 0.5em 1em 1em;overflow-x: auto;text-indent: 0px;text-align: left;line-height: 1.75;margin: 0px;white-space: pre-wrap;><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">import</span></span><span leaf=""> java.util.concurrent.CompletableFuture;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">import</span></span><span leaf=""> java.util.function.Function;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">import</span></span><span leaf=""> java.util.function.Consumer;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">public</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">class</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(230, 192, 123);"><span leaf="">FunctionWithConsumerAsync</span></span><span leaf=""> {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">public</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">static</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">void</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(97, 174, 238);"><span leaf="">main</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf="">(String[] args)</span></span><span leaf=""> {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 假设我们有一个异步任务:获取用户信息</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> Function <integer, completablefuture<string>> fetchUserInfo = userId -> </integer,></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> CompletableFuture.supplyAsync(() -> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"User"</span></span><span leaf=""> + userId);</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 定义一个 Consumer 用于处理异步结果</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> Consumer <string> printUserInfo = userInfo -> System.out.println( </string></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"Fetched user info: "</span></span><span leaf=""> + userInfo);</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 异步获取用户信息并处理</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> fetchUserInfo.apply(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">123</span></span><span leaf="">)</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> .thenAccept(printUserInfo); </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 使用 Consumer 处理结果</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> }</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf="">}</span></code></pre> <h4 style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-size: 16.5px;font-weight: bold;margin: 2em 8px 0.5em;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(0, 152, 116);><span leaf="">解释:</span></h4> <ul style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));list-style: none;margin: 0px;padding: 0px 0px 0px 1.5em;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;color: rgb(63, 63, 63); class="list-paddingleft-1"> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">fetchUserInfo</span></code><span leaf=""> 是一个异步任务,它返回一个 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">CompletableFuture</span></code><span leaf="">,该异步任务会根据用户 ID 获取用户信息。</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">printUserInfo</span></code><span leaf=""> 是一个 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Consumer</span></code><span leaf="">,用于处理异步回调结果,打印用户信息。</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• 使用 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">thenAccept()</span></code><span leaf=""> 方法将 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Consumer</span></code><span leaf=""> 应用到异步结果上,这样可以在数据准备好后异步执行处理逻辑。</span> </section></li> </ul> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));margin: 1.5em 8px;text-align: justify;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">通过这种方式,我们可以清晰地将数据的获取与后续处理分离,使得异步编程变得更加简洁和易于理解。</span></p> <hr style="box-sizing: border-box;border: none;height: 1px;color: inherit;margin: 2em 0px;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, microsoft yahei, arial, sans-serif;font-size: 15px;transform-origin: 0px 0px;transform: scale(1, 0.5);background: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0));> <h3 style="box-sizing: border-box;border-width: 0px 0px 1px 4px;border-style: solid solid dashed;border-bottom-color: rgb(0, 152, 116);border-left-color: rgb(0, 152, 116);font-size: 18px;font-weight: bold;margin: 2em 8px 0.75em 0px;text-align: left;line-height: 1.2;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;padding-left: 12px;color: rgb(63, 63, 63);><span leaf="">4. </span><strong style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-weight: bold;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: inherit;color: rgb(0, 152, 116);><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 16.2px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Function</span></code><span leaf=""> 与高阶函数:动态创建多个转换器</span></strong></h3> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));margin: 1.5em 8px;text-align: justify;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">在一些复杂的应用场景中,我们可能需要根据不同的条件动态创建多个转换器,并将它们组合起来执行。通过高阶函数,我们可以非常灵活地实现这一需求。</span></p> <h4 style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-size: 16.5px;font-weight: bold;margin: 2em 8px 0.5em;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(0, 152, 116);><span leaf="">代码示例:</span></h4> <pre style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14px;margin: 10px 8px;color: rgb(171, 178, 191);background: rgb(40, 44, 52);text-align: left;line-height: 1.5;overflow-x: auto;border-radius: 8px;box-shadow: rgba(0, 0, 0.05) 0px inset;padding: !important;><span hidden style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));display: flex;padding: 10px 14px 0px;"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" width="45px" height="13px" viewbox="0 0 450 130"> <ellipse cx="50" cy="65" rx="50" ry="52" stroke="rgb(220,60,54)" stroke-width="2" fill="rgb(237,108,96)"></ellipse><ellipse cx="225" cy="65" rx="50" ry="52" stroke="rgb(218,151,33)" stroke-width="2" fill="rgb(247,193,81)"></ellipse><ellipse cx="400" cy="65" rx="50" ry="52" stroke="rgb(27,161,37)" stroke-width="2" fill="rgb(100,200,86)"></ellipse> </svg></span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: " fira code, menlo, operator mono, consolas, monaco, monospace;font-feature-settings: normal;font-variation-settings: normal;font-size: 15px;display: -webkit-box;padding: 0.5em 1em 1em;overflow-x: auto;text-indent: 0px;text-align: left;line-height: 1.75;margin: 0px;white-space: pre-wrap;><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">import</span></span><span leaf=""> java.util.function.Function;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">public</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">class</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(230, 192, 123);"><span leaf="">HigherOrderFunction</span></span><span leaf=""> {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">public</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">static</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">void</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(97, 174, 238);"><span leaf="">main</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf="">(String[] args)</span></span><span leaf=""> {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 定义一个高阶函数,生成基于某些条件的转换器</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> Function <string, function<integer, string>> createConverter = condition -> { </string,></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">if</span></span><span leaf=""> (</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"prefix"</span></span><span leaf="">.equals(condition)) {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">return</span></span><span leaf=""> number -> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"Prefix_"</span></span><span leaf=""> + number;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> } </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">else</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">if</span></span><span leaf=""> (</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"suffix"</span></span><span leaf="">.equals(condition)) {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">return</span></span><span leaf=""> number -> number + </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"_Suffix"</span></span><span leaf="">;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> } </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">else</span></span><span leaf=""> {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">return</span></span><span leaf=""> number -> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"NoConversion_"</span></span><span leaf=""> + number;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> }</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> };</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 根据不同条件创建转换器</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> Function <integer, string> prefixConverter = createConverter.apply( </integer,></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"prefix"</span></span><span leaf="">);</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> Function <integer, string> suffixConverter = createConverter.apply( </integer,></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"suffix"</span></span><span leaf="">);</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 使用生成的转换器</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> System.out.println(prefixConverter.apply(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">123</span></span><span leaf="">)); </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 输出 Prefix_123</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> System.out.println(suffixConverter.apply(</span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">123</span></span><span leaf="">)); </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 输出 123_Suffix</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> }</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf="">}</span></code></pre> <h4 style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-size: 16.5px;font-weight: bold;margin: 2em 8px 0.5em;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(0, 152, 116);><span leaf="">解释:</span></h4> <ul style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));list-style: none;margin: 0px;padding: 0px 0px 0px 1.5em;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;color: rgb(63, 63, 63); class="list-paddingleft-1"> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">createConverter</span></code><span leaf=""> 是一个高阶函数,根据传入的条件动态生成不同的 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Function</span></code><span leaf="">。</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">prefixConverter</span></code><span leaf=""> 和 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">suffixConverter</span></code><span leaf=""> 是基于条件生成的转换器,分别为整数加上前缀或后缀。</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• 这种方式让我们能够根据不同的业务需求动态创建转换逻辑,避免了大量的条件判断语句。</span> </section></li> </ul> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));margin: 1.5em 8px;text-align: justify;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">通过这种高阶函数的技巧,我们可以在更复杂的应用中实现更加灵活和可维护的转换逻辑。</span></p> <hr style="box-sizing: border-box;border: none;height: 1px;color: inherit;margin: 2em 0px;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, microsoft yahei, arial, sans-serif;font-size: 15px;transform-origin: 0px 0px;transform: scale(1, 0.5);background: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0));> <h3 style="box-sizing: border-box;border-width: 0px 0px 1px 4px;border-style: solid solid dashed;border-bottom-color: rgb(0, 152, 116);border-left-color: rgb(0, 152, 116);font-size: 18px;font-weight: bold;margin: 2em 8px 0.75em 0px;text-align: left;line-height: 1.2;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;padding-left: 12px;color: rgb(63, 63, 63);><span leaf="">5. </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 16.2px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Function</span></code><span leaf=""> 与集合的组合:链式操作</span></h3> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));margin: 1.5em 8px;text-align: justify;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">链式操作是函数式编程中的一种常见模式,通过将多个 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Function</span></code><span leaf=""> 组合在一起,可以实现复杂的转换逻辑。这对于处理集合数据非常有用。</span></p> <h4 style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-size: 16.5px;font-weight: bold;margin: 2em 8px 0.5em;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(0, 152, 116);><span leaf="">代码示例:</span></h4> <pre style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14px;margin: 10px 8px;color: rgb(171, 178, 191);background: rgb(40, 44, 52);text-align: left;line-height: 1.5;overflow-x: auto;border-radius: 8px;box-shadow: rgba(0, 0, 0.05) 0px inset;padding: !important;><span hidden style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));display: flex;padding: 10px 14px 0px;"> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" width="45px" height="13px" viewbox="0 0 450 130"> <ellipse cx="50" cy="65" rx="50" ry="52" stroke="rgb(220,60,54)" stroke-width="2" fill="rgb(237,108,96)"></ellipse><ellipse cx="225" cy="65" rx="50" ry="52" stroke="rgb(218,151,33)" stroke-width="2" fill="rgb(247,193,81)"></ellipse><ellipse cx="400" cy="65" rx="50" ry="52" stroke="rgb(27,161,37)" stroke-width="2" fill="rgb(100,200,86)"></ellipse> </svg></span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: " fira code, menlo, operator mono, consolas, monaco, monospace;font-feature-settings: normal;font-variation-settings: normal;font-size: 15px;display: -webkit-box;padding: 0.5em 1em 1em;overflow-x: auto;text-indent: 0px;text-align: left;line-height: 1.75;margin: 0px;white-space: pre-wrap;><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">import</span></span><span leaf=""> java.util.List;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">import</span></span><span leaf=""> java.util.function.Function;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">import</span></span><span leaf=""> java.util.stream.Collectors;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">public</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">class</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(230, 192, 123);"><span leaf="">FunctionChainWithCollections</span></span><span leaf=""> {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">public</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">static</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">void</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(97, 174, 238);"><span leaf="">main</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf="">(String[] args)</span></span><span leaf=""> {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 创建一组用户年龄数据</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> List <integer> ages = List.of( </integer></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">25</span></span><span leaf="">, </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">30</span></span><span leaf="">, </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">35</span></span><span leaf="">, </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">40</span></span><span leaf="">, </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">45</span></span><span leaf="">);</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 定义一个 Function,表示年龄到年龄段的转换</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> Function <integer, string> ageToRange = age -> { </integer,></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">if</span></span><span leaf=""> (age < </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">30</span></span><span leaf="">) {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">return</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"Young"</span></span><span leaf="">;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> } </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">else</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">if</span></span><span leaf=""> (age < </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(209, 154, 102);"><span leaf="">40</span></span><span leaf="">) {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">return</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"Middle-aged"</span></span><span leaf="">;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> } </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">else</span></span><span leaf=""> {</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">return</span></span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"Old"</span></span><span leaf="">;</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> }</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> };</span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> </span><span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 定义一个 Function,表示将年龄段转换为推荐的健康活动</span></span><br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"><span leaf=""> Function <string, string< span> <br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"> <br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"> <span leaf="">> rangeToActivity = range -> {</span> <br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"> <span leaf=""> </span> <span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">switch</span></span> <span leaf=""> (range) {</span> <br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"> <span leaf=""> </span> <span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">case</span></span> <span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"Young"</span></span> <span leaf="">: </span> <span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">return</span></span> <span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"Running"</span></span> <span leaf="">;</span> <br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"> <span leaf=""> </span> <span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">case</span></span> <span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"Middle-aged"</span></span> <span leaf="">: </span> <span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">return</span></span> <span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"Cycling"</span></span> <span leaf="">;</span> <br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"> <span leaf=""> </span> <span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">case</span></span> <span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"Old"</span></span> <span leaf="">: </span> <span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">return</span></span> <span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"Walking"</span></span> <span leaf="">;</span> <br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"> <span leaf=""> </span> <span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">default</span></span> <span leaf="">: </span> <span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(249, 38, 114);"><span leaf="">return</span></span> <span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(152, 195, 121);"><span leaf="">"Unknown"</span></span> <span leaf="">;</span> <br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"> <span leaf=""> }</span> <br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"> <span leaf=""> };</span> <br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"> <br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"> <span leaf=""> </span> <span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 使用链式操作处理年龄数据</span></span> <br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"> <span leaf=""> List <string> activities = ages.stream() </string></span> <br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"> <span leaf=""> .map(ageToRange) </span> <span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 将年龄转换为年龄段</span></span> <br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"> <span leaf=""> .map(rangeToActivity) </span> <span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 将年龄段转换为活动推荐</span></span> <br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"> <span leaf=""> .collect(Collectors.toList());</span> <br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"> <br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"> <span leaf=""> System.out.println(activities); </span> <span style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));color: rgb(177, 142, 177);font-style: italic;"><span leaf="">// 输出 [Running, Running, Cycling, Cycling, Walking]</span></span> <br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"> <span leaf=""> }</span> <br style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));"> <span leaf="">}</span> </string,></span></code></pre> <h4 style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-size: 16.5px;font-weight: bold;margin: 2em 8px 0.5em;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;color: rgb(0, 152, 116);><span leaf="">解释:</span></h4> <ul style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));list-style: none;margin: 0px;padding: 0px 0px 0px 1.5em;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;color: rgb(63, 63, 63); class="list-paddingleft-1"> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">ageToRange</span></code><span leaf=""> 将年龄转换为年龄段("Young"、"Middle-aged"、"Old")。</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">rangeToActivity</span></code><span leaf=""> 将年龄段转换为健康活动推荐(如 "Running"、"Cycling" 等)。</span> </section></li> <li style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;text-indent: -1em;display: block;margin: 0.5em 8px;color: rgb(63, 63, 63);> <section> <span leaf="">• 通过链式调用,我们能够优雅地将年龄数据转换成健康活动推荐。</span> </section></li> </ul> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));margin: 1.5em 8px;text-align: justify;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">这种方法利用了 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Function</span></code><span leaf=""> 的组合特性,使得数据转换变得简洁、直观,并且易于扩展。</span></p> <hr style="box-sizing: border-box;border: none;height: 1px;color: inherit;margin: 2em 0px;text-align: left;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, microsoft yahei, arial, sans-serif;font-size: 15px;transform-origin: 0px 0px;transform: scale(1, 0.5);background: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0));> <h3 style="box-sizing: border-box;border-width: 0px 0px 1px 4px;border-style: solid solid dashed;border-bottom-color: rgb(0, 152, 116);border-left-color: rgb(0, 152, 116);font-size: 18px;font-weight: bold;margin: 2em 8px 0.75em 0px;text-align: left;line-height: 1.2;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;padding-left: 12px;color: rgb(63, 63, 63);><span leaf="">结语</span></h3> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));margin: 1.5em 8px;text-align: justify;line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-size: 15px;letter-spacing: 0.1em;color: rgb(63, 63, 63);><span leaf="">通过这些不同的 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Function</span></code><span leaf=""> 使用场景,我们可以看到它的强大功能:从异步处理、懒加载、到与 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Optional</span></code><span leaf="">、</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Predicate</span></code><span leaf=""> 等接口的结合,</span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Function</span></code><span leaf=""> 在 Java 开发中有着极其广泛的应用。这些实际的代码示例展示了 </span><code style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));font-family: -apple-system-font, BlinkMacSystemFont, " helvetica neue, pingfang sc, hiragino sans gb, microsoft yahei ui, yahei, arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 13.5px;text-align: left;line-height: 1.75;color: rgb(221, 17, 68);background: rgba(27, 31, 35, 0.05);padding: 3px 5px;border-radius: 4px;><span leaf="">Function</span></code><span leaf=""> 在复杂场景中的强大潜力,掌握这些技巧后,您将在开发过程中更加得心应手。</span></p> </section> <p style="box-sizing: border-box;border-width: 0px;border-style: solid;border-color: hsl(var(--border));margin: 0px;color: rgb(10, 10, 10);font-family: ui-sans-serif, system-ui, sans-serif, " apple color emoji, segoe ui symbol, noto emoji;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: start;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;font-size: 0px;line-height: 0;><span leaf=""> </span></p> <section> <span leaf=""><br></span> </section> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>
作者:微信小助手
<section data-tool="mdnice编辑器" data-website="https://www.mdnice.com" style="margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 10px;padding-right: 10px;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;font-family: Optima, PingFangSC-regular, serif;font-size: 16px;color: rgb(0, 0, 0);line-height: 1.5em;word-spacing: 0em;letter-spacing: 0em;word-break: break-word;overflow-wrap: break-word;text-align: left;"> <h2 data-tool="mdnice编辑器" style=" margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: center;line-height: 1.5em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: 100%;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;border-bottom-color: rgb(119, 48, 152);color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: 85%;height: auto;align-items: unset;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: block;font-weight: bold;flex-direction: unset;float: unset;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 10px;padding-left: 0px;padding-right: 0px; text-align: center;text-indent: 0em;text-shadow: none;transform: none;-webkit-box-reflect: unset; "><span leaf="">引言</span></span><span style="display: none;"></span></h2> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">在我们的日常开发工作中,</span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Filter</span></code><span leaf="">(过滤器)、</span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Interceptor</span></code><span leaf="">(拦截器)和 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">AOP</span></code><span leaf="">(面向切面编程)是非常常用的 3 种请求处理技术。在不同的应用场景中,使用它们都可以在不影响主业务逻辑的前提下为系统增加额外的功能。面试官去问这个问题的时候,一般是想考察求职者的技术深度和对框架机制的理解。本篇我们从 3 者的基本概念及使用来分析解答下这道面试题。</span></p> <h2 data-tool="mdnice编辑器" style=" margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: center;line-height: 1.5em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: 100%;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;border-bottom-color: rgb(119, 48, 152);color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: 85%;height: auto;align-items: unset;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: block;font-weight: bold;flex-direction: unset;float: unset;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 10px;padding-left: 0px;padding-right: 0px; text-align: center;text-indent: 0em;text-shadow: none;transform: none;-webkit-box-reflect: unset; "><span leaf="">Filter</span></span><span style="display: none;"></span></h2> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: flex;"><span style="display: none;"></span><span style="font-size: 20px;color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;font-weight: bold;display: block;"><span leaf="">什么是 Filter</span></span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Filter</span></code><span leaf=""> 是 Java </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Servlet</span></code><span leaf=""> 规范的一部分,定义在 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">javax.servlet</span></code><span leaf=""> 包中,</span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Filter</span></code><span leaf=""> 可以对 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Servlet</span></code><span leaf=""> 容器的所有 HTTP 请求(</span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">HttpServletRequest</span></code><span leaf="">)和响应(</span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">HttpServletResponse</span></code><span leaf="">)进行预处理或后处理操作。例如,在请求到达目标资源之前执行身份验证或设置字符编码,或者在响应返回给客户端前修改其响应内容格式。</span></p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: flex;"><span style="display: none;"></span><span style="font-size: 20px;color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;font-weight: bold;display: block;"><span leaf="">Filter 接口</span></span><span style="display: none;"></span></h3> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg k0ue4mipav882cnbmffjvlrxfiaoyowabg1n9gndbfbyylu3av0epdc78k5wnsukhhozztyffw9mdqxuoquchp80rlmqpmiibl 640?wx_fmt="svg&from=appmsg");""></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">package</span></span><span leaf=""> javax.servlet;</span><br><br><span style="color: #c678dd;line-height: 26px;"><span leaf="">import</span></span><span leaf=""> java.io.IOException;</span><br><br><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">interface</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">Filter</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">default</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">init</span></span><span style="line-height: 26px;"><span leaf="">(FilterConfig filterConfig)</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">throws</span></span><span leaf=""> ServletException </span></span><span leaf="">{}</span><br><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">doFilter</span></span><span style="line-height: 26px;"><span leaf="">(ServletRequest request, ServletResponse response, FilterChain chain)</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">throws</span></span><span leaf=""> IOException, ServletException</span></span><span leaf="">;</span><br><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">default</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">destroy</span></span><span style="line-height: 26px;"><span leaf="">()</span></span><span leaf=""> </span></span><span leaf="">{}</span><br><span leaf="">}</span><br></code></pre> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">项目中自定义过滤器需实现该接口,接口中的 3 个方法就是 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Filter</span></code><span leaf=""> 的整个生命周期。</span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">init()</span></code><span leaf="">-初始化、</span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">doFilter()</span></code><span leaf="">-执行过滤逻辑、</span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">destroy()</span></code><span leaf="">-销毁。</span></p> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <p style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;height: auto;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">init方法</span></code><span leaf="">:Web 容器在启动时,会触发每个 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;height: auto;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Filter</span></code><span leaf=""> 实例的 init 方法调用并传递一个 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;height: auto;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">FilterConfig</span></code><span leaf=""> 对象,该配置允许过滤器获取初始化参数以及 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;height: auto;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">ServletContext</span></code><span leaf=""> 上下文对象,从而加载任何所需的资源。该方法在 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;height: auto;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Filter</span></code><span leaf=""> 的整个生命周期中仅会在初始化时被调用一次。</span></p> <blockquote style="margin-top: 20px;margin-bottom: 20px;margin-left: 0px;margin-right: 0px;padding-top: 10px;padding-bottom: 10px;padding-left: 20px;padding-right: 10px;border-top-style: none;border-bottom-style: none;border-left-style: solid;border-right-style: solid;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 1px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgb(150, 84, 181);border-right-color: rgb(150, 84, 181);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;background-attachment: scroll;background-clip: border-box;background-color: rgb(251, 249, 253);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;display: block;overflow-x: auto;overflow-y: auto;"> <span style="display: none;color: rgb(0, 0, 0);font-size: 16px;line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: normal;"></span> <p style="text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;margin-top: 0px;margin-right: 0px;margin-bottom: 0px;margin-left: 0px;"><span leaf="">该方法如果抛出异常,Web 容器就会认为这个过滤器无法正常工作,因此不会将它加入到过滤器链中,无法提供后续的请求过滤工作。</span></p> </blockquote> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <p style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;height: auto;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">doFilter方法</span></code><span leaf="">:该方法为 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;height: auto;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Filter</span></code><span leaf=""> 的核心工作方法,每一次请求都会调用该方法。</span></p> <blockquote style="margin-top: 20px;margin-bottom: 20px;margin-left: 0px;margin-right: 0px;padding-top: 10px;padding-bottom: 10px;padding-left: 20px;padding-right: 10px;border-top-style: none;border-bottom-style: none;border-left-style: solid;border-right-style: solid;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 1px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgb(150, 84, 181);border-right-color: rgb(150, 84, 181);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;background-attachment: scroll;background-clip: border-box;background-color: rgb(251, 249, 253);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;display: block;overflow-x: auto;overflow-y: auto;"> <span style="display: none;color: rgb(0, 0, 0);font-size: 16px;line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: normal;"></span> <p style="text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;margin-top: 0px;margin-right: 0px;margin-bottom: 0px;margin-left: 0px;"><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;height: auto;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">FilterChain</span></code><span leaf=""> 接口参数由具体的 Servlet 容器实现并提供。每个过滤器的 doFilter 方法都会接收一个 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;height: auto;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">FilterChain</span></code><span leaf=""> 对象作为参数。在这个方法内部,过滤器可以选择:</span></p> </blockquote> </section></li> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">直接处理请求/响应。</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">调用 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">chain.doFilter(request, response)</span></code><span leaf=""> 将请求传递给下一个过滤器或目标资源。</span> </section></li> </ul> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <p style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;height: auto;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">destroy方法</span></code><span leaf="">:Web 容器在销毁时,会触发每个 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;height: auto;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Filter</span></code><span leaf=""> 实例的 destroy 方法调用,清理过滤器所有持有的资源(如内存、文件句柄、线程等)。该方法在 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;height: auto;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Filter</span></code><span leaf=""> 的整个生命周期中也仅会执行一次。</span></p> </section></li> </ul> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: flex;"><span style="display: none;"></span><span style="font-size: 20px;color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;font-weight: bold;display: block;"><span leaf="">Filter 的配置使用</span></span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">在 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">SpringBoot</span></code><span leaf=""> 项目中可以使用如下几种配置方式:</span></p> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">使用 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">@WebFilter</span></code><span leaf=""> 注解 + </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">@ServletComponentScan</span></code><span leaf=""> 注解</span> </section></li> </ul> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">在过滤器类上使用 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">@WebFilter</span></code><span leaf=""> 注解来定义 URL 模式和其他属性</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg k0ue4mipav882cnbmffjvlrxfiaoyowabg1n9gndbfbyylu3av0epdc78k5wnsukhhozztyffw9mdqxuoquchp80rlmqpmiibl 640?wx_fmt="svg&from=appmsg");""></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">package</span></span><span leaf=""> com.example.filter;</span><br><br><span style="color: #61aeee;line-height: 26px;"><span leaf="">@WebFilter</span></span><span leaf="">(urlPatterns = </span><span style="color: #98c379;line-height: 26px;"><span leaf="">"/*"</span></span><span leaf="">, filterName = </span><span style="color: #98c379;line-height: 26px;"><span leaf="">"exampleFilter"</span></span><span leaf="">)</span><br><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">class</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">ExampleFilter</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">implements</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">Filter</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Override</span></span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">init</span></span><span style="line-height: 26px;"><span leaf="">(FilterConfig filterConfig)</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">throws</span></span><span leaf=""> ServletException </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 初始化逻辑...</span></span><br><span leaf=""> }</span><br><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Override</span></span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">doFilter</span></span><span style="line-height: 26px;"><span leaf="">(ServletRequest request, ServletResponse response, FilterChain chain)</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">throws</span></span><span leaf=""> IOException, ServletException </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 传递给下一个过滤器或目标资源</span></span><br><span leaf=""> chain.doFilter(request, response);</span><br><span leaf=""> }</span><br><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Override</span></span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">destroy</span></span><span style="line-height: 26px;"><span leaf="">()</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 清理资源...</span></span><br><span leaf=""> }</span><br><span leaf="">}</span><br></code></pre> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">在启动类或者任意配置类上加上 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">@ServletComponentScan</span></code><span leaf=""> 注解来让 Spring Boot 自动扫描并注册这些过滤器。</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg k0ue4mipav882cnbmffjvlrxfiaoyowabg1n9gndbfbyylu3av0epdc78k5wnsukhhozztyffw9mdqxuoquchp80rlmqpmiibl 640?wx_fmt="svg&from=appmsg");""></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #61aeee;line-height: 26px;"><span leaf="">@SpringBootApplication</span></span><br><span style="color: #61aeee;line-height: 26px;"><span leaf="">@ServletComponentScan</span></span><span leaf="">(basePackages = </span><span style="color: #98c379;line-height: 26px;"><span leaf="">"com.example.filter"</span></span><span leaf="">) </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 指定扫描包路径</span></span><br><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">class</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">MyApplication</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">static</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">main</span></span><span style="line-height: 26px;"><span leaf="">(String[] args)</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> SpringApplication.run(MyApplication</span><span style="line-height: 26px;"><span leaf="">.</span><span style="color: #c678dd;line-height: 26px;"><span leaf="">class</span></span><span leaf="">, </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">args</span></span><span leaf="">)</span></span><span leaf="">;</span><br><span leaf=""> }</span><br><span leaf="">}</span><br></code></pre> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">使用 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">FilterRegistrationBean</span></code><span leaf=""> 进行注册</span> </section></li> </ul> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg k0ue4mipav882cnbmffjvlrxfiaoyowabg1n9gndbfbyylu3av0epdc78k5wnsukhhozztyffw9mdqxuoquchp80rlmqpmiibl 640?wx_fmt="svg&from=appmsg");""></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Configuration</span></span><br><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">class</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">FilterConfig</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Bean</span></span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> FilterRegistrationBean <examplefilter> </examplefilter></span><span style="color: #61aeee;line-height: 26px;"><span leaf="">customFilterRegistration</span></span><span style="line-height: 26px;"><span leaf="">()</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> FilterRegistrationBean <examplefilter> registrationBean = </examplefilter></span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> FilterRegistrationBean<>();</span><br><br><span leaf=""> ExampleFilter customFilter = </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> ExampleFilter();</span><br><span leaf=""> registrationBean.setFilter(customFilter);</span><br><span leaf=""> registrationBean.addUrlPatterns(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"/*"</span></span><span leaf="">);</span><br><span leaf=""> registrationBean.setOrder(</span><span style="color: #d19a66;line-height: 26px;"><span leaf="">1</span></span><span leaf="">); </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 设置过滤器的执行顺序</span></span><br><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 添加初始化参数</span></span><br><span leaf=""> registrationBean.addInitParameter(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"encoding"</span></span><span leaf="">, </span><span style="color: #98c379;line-height: 26px;"><span leaf="">"UTF-8"</span></span><span leaf="">);</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">return</span></span><span leaf=""> registrationBean;</span><br><span leaf=""> }</span><br><span leaf="">}</span><br></code></pre> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">直接使用 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">@Component</span></code><span leaf=""> 注解:这种方式可以让 Spring 自动将过滤器组件化,默认会应用到所有请求路径。</span> </section></li> </ul> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg k0ue4mipav882cnbmffjvlrxfiaoyowabg1n9gndbfbyylu3av0epdc78k5wnsukhhozztyffw9mdqxuoquchp80rlmqpmiibl 640?wx_fmt="svg&from=appmsg");""></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Component</span></span><br><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">class</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">ExampleFilter</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">implements</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">Filter</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Override</span></span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">init</span></span><span style="line-height: 26px;"><span leaf="">(FilterConfig filterConfig)</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">throws</span></span><span leaf=""> ServletException </span></span><span leaf="">{}</span><br><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Override</span></span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">doFilter</span></span><span style="line-height: 26px;"><span leaf="">(ServletRequest request, ServletResponse response, FilterChain chain)</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">throws</span></span><span leaf=""> IOException, ServletException </span></span><span leaf="">{</span><br><span leaf=""> chain.doFilter(request, response);</span><br><span leaf=""> }</span><br><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Override</span></span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">destroy</span></span><span style="line-height: 26px;"><span leaf="">()</span></span><span leaf=""> </span></span><span leaf="">{}</span><br><span leaf="">}</span><br></code></pre> <h2 data-tool="mdnice编辑器" style=" margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: center;line-height: 1.5em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: 100%;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;border-bottom-color: rgb(119, 48, 152);color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: 85%;height: auto;align-items: unset;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: block;font-weight: bold;flex-direction: unset;float: unset;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 10px;padding-left: 0px;padding-right: 0px; text-align: center;text-indent: 0em;text-shadow: none;transform: none;-webkit-box-reflect: unset; "><span leaf="">Interceptor</span></span><span style="display: none;"></span></h2> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: flex;"><span style="display: none;"></span><span style="font-size: 20px;color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;font-weight: bold;display: block;"><span leaf="">什么是 Interceptor</span></span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Interceptor</span></code><span leaf=""> 是 Spring MVC 框架的一部分,是位于 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">org.springframework.web.servlet</span></code><span leaf=""> 包中的 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">HandlerInterceptor</span></code><span leaf=""> 接口,用于在请求处理之前或之后执行特定逻辑。与 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Filter</span></code><span leaf=""> 不同的是,</span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Interceptor</span></code><span leaf=""> 不依赖于 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Servlet</span></code><span leaf=""> 容器,它是 Spring 框架独有的。</span></p> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: flex;"><span style="display: none;"></span><span style="font-size: 20px;color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;font-weight: bold;display: block;"><span leaf="">HandlerInterceptor 接口</span></span><span style="display: none;"></span></h3> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg k0ue4mipav882cnbmffjvlrxfiaoyowabg1n9gndbfbyylu3av0epdc78k5wnsukhhozztyffw9mdqxuoquchp80rlmqpmiibl 640?wx_fmt="svg&from=appmsg");""></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">/**</span><br><span leaf=""> * A HandlerInterceptor gets called before the appropriate HandlerAdapter triggers the execution of the handler itself.</span><br><span leaf=""> * This mechanism can be used for a large field of preprocessing aspects, e.g. for authorization checks,</span><br><span leaf=""> * or common handler behavior like locale or theme changes.</span><br><span leaf=""> * Its main purpose is to allow for factoring out repetitive handler code.</span><br><span leaf=""> */</span></span><br><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">interface</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">HandlerInterceptor</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">default</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">boolean</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">preHandle</span></span><span style="line-height: 26px;"><span leaf="">(HttpServletRequest request, HttpServletResponse response, Object handler)</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">throws</span></span><span leaf=""> Exception </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">return</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">true</span></span><span leaf="">;</span><br><span leaf=""> }</span><br><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">default</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">postHandle</span></span><span style="line-height: 26px;"><span leaf="">(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView)</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">throws</span></span><span leaf=""> Exception </span></span><span leaf="">{</span><br><span leaf=""> }</span><br><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">default</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">afterCompletion</span></span><span style="line-height: 26px;"><span leaf="">(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex)</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">throws</span></span><span leaf=""> Exception </span></span><span leaf="">{</span><br><span leaf=""> }</span><br><span leaf="">}</span><br></code></pre> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">接口注释意思大致是说,</span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">HandlerInterceptor</span></code><span leaf=""> 是在通过 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">HandlerAdapter</span></code><span leaf=""> 执行查找到的 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">handler</span></code><span leaf=""> 之前被调用,这种机制主要目的是为了减少重复代码,用于大量的程序预处理工作,比如授权检查等。</span></p> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">preHandle方法</span></code><span leaf="">:在 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">controller</span></code><span leaf=""> 方法调用之前,按照 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Interceptor</span></code><span leaf=""> 链</span><strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">顺序执行</span></strong><span leaf="">,进行权限检查等请求前处理操作。</span> <blockquote style="margin-top: 20px;margin-bottom: 20px;margin-left: 0px;margin-right: 0px;padding-top: 10px;padding-bottom: 10px;padding-left: 20px;padding-right: 10px;border-top-style: none;border-bottom-style: none;border-left-style: solid;border-right-style: solid;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 1px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgb(150, 84, 181);border-right-color: rgb(150, 84, 181);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;background-attachment: scroll;background-clip: border-box;background-color: rgb(251, 249, 253);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;display: block;overflow-x: auto;overflow-y: auto;"> <span style="display: none;color: rgb(0, 0, 0);font-size: 16px;line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: normal;"></span> <p style="text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;margin-top: 0px;margin-right: 0px;margin-bottom: 0px;margin-left: 0px;"><span leaf="">如果该方法返回了 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;height: auto;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">false</span></code><span leaf="">,那么不仅当前 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;height: auto;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Interceptor</span></code><span leaf=""> 会终止执行,整个拦截器链都会被终止。</span></p> </blockquote> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">postHandle方法</span></code><span leaf="">:在 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">controller</span></code><span leaf=""> 方法调用之后返回 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">ModelAndView</span></code><span leaf=""> 之前执行,与 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">preHandle</span></code><span leaf=""> 不同的是,</span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">postHandle</span></code><span leaf=""> 是按照</span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Interceptor</span></code><span leaf=""> 链</span><strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">逆序执行</span></strong><span leaf="">的。</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">afterCompletion方法</span></code><span leaf="">:在整个请求完成后调用,通常用于资源清理或日志记录。</span> </section></li> </ul> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">执行顺序:</span></strong><span leaf=""><img class="rich_pages wxw-img" data-imgfileid="100003274" src="/upload/f35b1a3bf81f30cdc9cfb98e05b73b18.png" data-type="png" style="display: block;margin-top: 0px;margin-right: auto;margin-bottom: 0px;margin-left: auto;max-width: 100%;"></span></p> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">下面我们通过 Spring MVC 在实际分发处理请求时的源码具体看下 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Interceptor</span></code><span leaf=""> 的执行情况(源码出自 spring-framework-5.0.x):</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg k0ue4mipav882cnbmffjvlrxfiaoyowabg1n9gndbfbyylu3av0epdc78k5wnsukhhozztyffw9mdqxuoquchp80rlmqpmiibl 640?wx_fmt="svg&from=appmsg");""></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">protected</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">doDispatch</span></span><span style="line-height: 26px;"><span leaf="">(HttpServletRequest request, HttpServletResponse response)</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">throws</span></span><span leaf=""> Exceptio </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 此处用 processedRequest 接收了用户的 request 请求</span></span><br><span leaf=""> HttpServletRequest processedRequest = request;</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// HandlerExecutionChain 局部变量</span></span><br><span leaf=""> HandlerExecutionChain mappedHandler = </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">null</span></span><span leaf="">;</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 标记一下是否解析了文件类型的数据,如果有最终需要清理操作</span></span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">boolean</span></span><span leaf=""> multipartRequestParsed = </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">false</span></span><span leaf="">;</span><br><br><span leaf=""> WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);</span><br><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">try</span></span><span leaf=""> {</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// ModelAndView 局部变量</span></span><br><span leaf=""> ModelAndView mv = </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">null</span></span><span leaf="">;</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 处理异常局部变量</span></span><br><span leaf=""> Exception dispatchException = </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">null</span></span><span leaf="">;</span><br><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">try</span></span><span leaf=""> {</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">/**</span><br><span leaf=""> * 判断一下是否是文件上传请求。</span><br><span leaf=""> * 如果请求是 POST 请求,并且 Context-Type 是以 multipart/ 开头的就认为是文件上传的请求。</span><br><span leaf=""> * 需要注意的是,若是这里被认定为文件上传请求,processedRequest 和 request 将不再指向同一对象</span><br><span leaf=""> * 这里返回的是 MultipartHttpServletRequest。</span><br><span leaf=""> */</span></span><br><span leaf=""> processedRequest = checkMultipart(request);</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 两个请求不再相同,进行文件上传标记,用于后续清理操作</span></span><br><span leaf=""> multipartRequestParsed = (processedRequest != request);</span><br><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">/**</span><br><span leaf=""> * 向 HandlerMapping 请求查找 HandlerExecutionChain</span><br><span leaf=""> * 找到一个处理器,如果没有找到对应的处理类的话,这里通常会返回404。</span><br><span leaf=""> */</span></span><br><span leaf=""> mappedHandler = getHandler(processedRequest);</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 如果没找到对应的处理器,则抛出异常</span></span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 相信大家都见过 'No mapping for GET /xxxx',就是这里抛出的</span></span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">if</span></span><span leaf=""> (mappedHandler == </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">null</span></span><span leaf="">) {</span><br><span leaf=""> noHandlerFound(processedRequest, response);</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">return</span></span><span leaf="">;</span><br><span leaf=""> }</span><br><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 根据查找到的 Handler 请求查找能够进行处理的 HandlerAdapter</span></span><br><span leaf=""> HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());</span><br><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 判断自上次请求后是否有修改,没有修改直接返回响应</span></span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 如果是GET请求,且内容没有变化的话,就直接返回</span></span><br><span leaf=""> String method = request.getMethod();</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">boolean</span></span><span leaf=""> isGet = </span><span style="color: #98c379;line-height: 26px;"><span leaf="">"GET"</span></span><span leaf="">.equals(method);</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">if</span></span><span leaf=""> (isGet || </span><span style="color: #98c379;line-height: 26px;"><span leaf="">"HEAD"</span></span><span leaf="">.equals(method)) {</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">long</span></span><span leaf=""> lastModified = ha.getLastModified(request, mappedHandler.getHandler());</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">if</span></span><span leaf=""> (log.isDebugEnabled()) {</span><br><span leaf=""> log.debug(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"Last-Modified value for ["</span></span><span leaf=""> + getRequestUri(request) + </span><span style="color: #98c379;line-height: 26px;"><span leaf="">"] is: "</span></span><span leaf=""> + lastModified);</span><br><span leaf=""> }</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">if</span></span><span leaf=""> (</span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">return</span></span><span leaf="">;</span><br><span leaf=""> }</span><br><span leaf=""> }</span><br><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">/**</span><br><span leaf=""> * <<<<<<<<<这里到了我们本节内容,拦截器的执行了>>>>>>>>></span><br><span leaf=""> * 这里通过 applyPreHandle 方法,按顺序依次执行 HandlerInterceptor 的 preHandle 方法</span><br><span leaf=""> * 可以看到,如果任一 HandlerInterceptor 的 preHandle 方法返回了 false, 则整个拦截器连</span><br><span leaf=""> * 不再继续进行处理。</span><br><span leaf=""> */</span></span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">if</span></span><span leaf=""> (!mappedHandler.applyPreHandle(processedRequest, response)) {</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">return</span></span><span leaf="">;</span><br><span leaf=""> }</span><br><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">/**</span><br><span leaf=""> * 通过 HandlerAdapter 执行查找到的 handler</span><br><span leaf=""> * 这里真正执行我们 controller 中的方法逻辑,返回一个 ModelAndView</span><br><span leaf=""> */</span></span><br><span leaf=""> mv = ha.handle(processedRequest, response, mappedHandler.getHandler());</span><br><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">/**</span><br><span leaf=""> * 检查是否已经开始处理并发请求,如果并发处理已经开始,那么当前的请求线程就可以返回了,而不会等待异步操 * 作的结果,也就不会再执行拦截器 PostHandle 之类的操作了。</span><br><span leaf=""> */</span></span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">if</span></span><span leaf=""> (asyncManager.isConcurrentHandlingStarted()) {</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">return</span></span><span leaf="">;</span><br><span leaf=""> }</span><br><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 如果我们没有设置 viewName,就采用默认的,否则采用我们自己的</span></span><br><span leaf=""> applyDefaultViewName(processedRequest, mv);</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// <<<<<<<<< 这里,通过 applyPostHandle 逆序执行 HandlerInterceptor 的 postHandle 方法>>>>>>>>></span></span><br><span leaf=""> mappedHandler.applyPostHandle(processedRequest, response, mv);</span><br><span leaf=""> }</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">catch</span></span><span leaf=""> (Exception ex) {</span><br><span leaf=""> dispatchException = ex;</span><br><span leaf=""> }</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">catch</span></span><span leaf=""> (Throwable err) {</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// As of 4.3, we're processing Errors thrown from handler methods as well,</span></span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// making them available for @ExceptionHandler methods and other scenarios.</span></span><br><span leaf=""> dispatchException = </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> NestedServletException(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"Handler dispatch failed"</span></span><span leaf="">, err);</span><br><span leaf=""> }</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 渲染视图填充 Model,如果有异常渲染异常页面</span></span><br><span leaf=""> processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);</span><br><span leaf=""> }</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">catch</span></span><span leaf=""> (Exception ex) {</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 如果有异常按倒序执行所有 HandlerInterceptor 的 afterCompletion 方法</span></span><br><span leaf=""> triggerAfterCompletion(processedRequest, response, mappedHandler, ex);</span><br><span leaf=""> }</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">catch</span></span><span leaf=""> (Throwable err) {</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 如果有异常按倒序执行所有 HandlerInterceptor 的 afterCompletion 方法</span></span><br><span leaf=""> triggerAfterCompletion(processedRequest, response, mappedHandler,</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> NestedServletException(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"Handler processing failed"</span></span><span leaf="">, err));</span><br><span leaf=""> }</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">finally</span></span><span leaf=""> {</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">if</span></span><span leaf=""> (asyncManager.isConcurrentHandlingStarted()) {</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// Instead of postHandle and afterCompletion</span></span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">if</span></span><span leaf=""> (mappedHandler != </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">null</span></span><span leaf="">) {</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 倒序执行所有 HandlerInterceptor 的 afterCompletion 方法</span></span><br><span leaf=""> mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);</span><br><span leaf=""> }</span><br><span leaf=""> }</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">else</span></span><span leaf=""> {</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// Clean up any resources used by a multipart request.</span></span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">if</span></span><span leaf=""> (multipartRequestParsed) {</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 如果请求包含文件类型的数据则进行相关清理工作</span></span><br><span leaf=""> cleanupMultipart(processedRequest);</span><br><span leaf=""> }</span><br><span leaf=""> }</span><br><span leaf=""> }</span><br><span leaf="">}</span><br></code></pre> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">上述源码中,其实不仅仅是拦截器的执行顺序了,而是 Spring MVC 处理客户端请求的整个过程。如下图,可以很直观的看出拦截器的执行时机与顺序。</span></p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <span leaf=""><img class="rich_pages wxw-img" data-imgfileid="100003276" src="/upload/2453abb72c876e15ed9de83ddccc013d.jpg" data-type="jpeg" style="display: block;margin-top: 0px;margin-right: auto;margin-bottom: 0px;margin-left: auto;max-width: 100%;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"></span> <figcaption style="color: rgb(136, 136, 136);font-size: 14px;line-height: 1.5em;letter-spacing: 0em;text-align: center;font-weight: normal;margin-top: 5px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"> <span leaf="">图片来源于网络,侵权请联系删除</span> </figcaption> </figure> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: flex;"><span style="display: none;"></span><span style="font-size: 20px;color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;font-weight: bold;display: block;"><span leaf="">Interceptor 的配置使用</span></span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">自定义拦截器,实现 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">HandlerInterceptor</span></code><span leaf=""> 接口</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg k0ue4mipav882cnbmffjvlrxfiaoyowabg1n9gndbfbyylu3av0epdc78k5wnsukhhozztyffw9mdqxuoquchp80rlmqpmiibl 640?wx_fmt="svg&from=appmsg");""></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">class</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">MyInterceptor</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">implements</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">HandlerInterceptor</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Override</span></span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">boolean</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">preHandle</span></span><span style="line-height: 26px;"><span leaf="">(HttpServletRequest request, HttpServletResponse response, Object handler)</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">throws</span></span><span leaf=""> Exception </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 在这里添加拦截逻辑,例如身份验证或日志记录</span></span><br><span leaf=""> System.out.println(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"MyInterceptor preHandle: "</span></span><span leaf=""> + request.getRequestURI());</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">return</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">true</span></span><span leaf="">; </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 返回 true 继续处理请求,返回 false 中断请求</span></span><br><span leaf=""> }</span><br><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Override</span></span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">postHandle</span></span><span style="line-height: 26px;"><span leaf="">(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">throws</span></span><span leaf=""> Exception </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 在视图渲染之前执行的逻辑</span></span><br><span leaf=""> System.out.println(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"MyInterceptor postHandle: "</span></span><span leaf=""> + request.getRequestURI());</span><br><span leaf=""> }</span><br><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Override</span></span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">afterCompletion</span></span><span style="line-height: 26px;"><span leaf="">(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">throws</span></span><span leaf=""> Exception </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 请求完成后的逻辑,比如资源清理</span></span><br><span leaf=""> System.out.println(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"MyInterceptor afterCompletion: "</span></span><span leaf=""> + request.getRequestURI());</span><br><span leaf=""> }</span><br><span leaf="">}</span><br></code></pre> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">实现 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">WebMvcConfigurer</span></code><span leaf=""> 接口并重写 </span><code style="color: rgb(150, 84, 181);font-size: 14px;line-height: 1.8em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">addInterceptors</span></code><span leaf=""> 方法,将拦截器注册到 Spring MVC 的拦截器链中</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg k0ue4mipav882cnbmffjvlrxfiaoyowabg1n9gndbfbyylu3av0epdc78k5wnsukhhozztyffw9mdqxuoquchp80rlmqpmiibl 640?wx_fmt="svg&from=appmsg");""></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Configuration</span></span><br><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">class</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">WebConfig</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">implements</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">WebMvcConfigurer</span></span><span leaf=""> </span></span><span leaf="">{</span><br><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Override</span></span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">addInterceptors</span></span><span style="line-height: 26px;"><span leaf="">(InterceptorRegistry registry)</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 添加拦截器,并指定拦截路径模式</span></span><br><span leaf=""> registry.addInterceptor(</span><span style="color: #c678dd;line-height: 26px;"><span leaf="">new</span></span><span leaf=""> MyInterceptor())</span><br><span leaf=""> .addPathPatterns(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"/**"</span></span><span leaf="">) </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 拦截所有路径</span></span><br><span leaf=""> .excludePathPatterns(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"/static/**"</span></span><span leaf="">, </span><span style="color: #98c379;line-height: 26px;"><span leaf="">"/login"</span></span><span leaf="">, </span><span style="color: #98c379;line-height: 26px;"><span leaf="">"/register"</span></span><span leaf="">); </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 排除静态资源和某些 URL</span></span><br><span leaf=""> }</span><br><span leaf="">}</span><br></code></pre> <h2 data-tool="mdnice编辑器" style=" margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: center;line-height: 1.5em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: 100%;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;border-bottom-color: rgb(119, 48, 152);color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: 85%;height: auto;align-items: unset;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: block;font-weight: bold;flex-direction: unset;float: unset;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 10px;padding-left: 0px;padding-right: 0px; text-align: center;text-indent: 0em;text-shadow: none;transform: none;-webkit-box-reflect: unset; "><span leaf="">AOP(Aspect-Oriented Programming)</span></span><span style="display: none;"></span></h2> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: flex;"><span style="display: none;"></span><span style="font-size: 20px;color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;font-weight: bold;display: block;"><span leaf="">什么是 AOP</span></span><span style="display: none;"></span></h3> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">AOP(Aspect-Oriented Programming),即面向切面编程,是一种编程范式,目的是通过分离横切关注点(如事务管理、日志记录)来提高代码的模块化程度。AOP 允许开发者定义“切面”(Aspects),通过这些切面可以在不改变业务逻辑的情况下增强现有业务功能。</span></p> <blockquote style="margin-top: 20px;margin-bottom: 20px;margin-left: 0px;margin-right: 0px;padding-top: 10px;padding-bottom: 10px;padding-left: 20px;padding-right: 10px;border-top-style: none;border-bottom-style: none;border-left-style: solid;border-right-style: solid;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 1px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgb(150, 84, 181);border-right-color: rgb(150, 84, 181);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;background-attachment: scroll;background-clip: border-box;background-color: rgb(251, 249, 253);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;display: block;overflow-x: auto;overflow-y: auto;"> <span style="display: none;color: rgb(0, 0, 0);font-size: 16px;line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: normal;"></span> <p style="text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;margin-top: 0px;margin-right: 0px;margin-bottom: 0px;margin-left: 0px;"><span leaf="">AOP 是一种编程思想,Spring AOP 是 Spring 框架提供的 AOP 实现。</span></p> </blockquote> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: flex;"><span style="display: none;"></span><span style="font-size: 20px;color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;font-weight: bold;display: block;"><span leaf="">AOP 核心概念</span></span><span style="display: none;"></span></h3> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">切面(Aspect)</span></strong><span leaf="">:一个模块化的特殊类,包含通知和切入点,用来实现特定的横切逻辑。</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">通知(Advice)</span></strong><span leaf="">:在特定连接点(Join Point)执行的动作,例如前置通知(在目标方法调用之前执行的通知)。</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">连接点(Join Point)</span></strong><span leaf="">:程程序执行过程中的一个点,例如方法调用或异常抛出的地方。在 Spring AOP 中,连接点指的是应用程序中所有可能被拦截的方法执行点。</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">切入点(Pointcut)</span></strong><span leaf="">:用于匹配连接点的表达式,决定了哪些连接点会应用切面的通知。Spring AOP 使用 AspectJ 的切入点表达式语言。例如:</span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">@Pointcut("execution(* com.example.service..*.*(..))")</span></code> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">引入(Introduction)</span></strong><span leaf="">:为现有的类添加新方法或属性的能力。</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">目标对象(Target Object)</span></strong><span leaf="">:目标对象是指被一个或多个切面所通知的对象,也就是需要对其方法调用进行增强的对象。使用 AOP 时,这些对象会被代理,以便可以在它们的方法调用前后插入额外的行为。</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">代理(Proxy)</span></strong><span leaf="">:由 AOP 框架创建的对象,用来实现对目标对象的增强。有两种主要类型的 AOP 代理:JDK 动态代理和 CGLIB 代理。</span> </section></li> </ul> <blockquote style="margin-top: 20px;margin-bottom: 20px;margin-left: 0px;margin-right: 0px;padding-top: 10px;padding-bottom: 10px;padding-left: 20px;padding-right: 10px;border-top-style: none;border-bottom-style: none;border-left-style: solid;border-right-style: solid;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 1px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgb(150, 84, 181);border-right-color: rgb(150, 84, 181);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;background-attachment: scroll;background-clip: border-box;background-color: rgb(251, 249, 253);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;display: block;overflow-x: auto;overflow-y: auto;"> <span style="display: none;color: rgb(0, 0, 0);font-size: 16px;line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: normal;"></span> <p style="text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;margin-top: 0px;margin-right: 0px;margin-bottom: 0px;margin-left: 0px;"><span leaf="">Spring AOP 如何创建代理:</span></p> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">默认情况下,如果目标对象实现了至少一个接口,Spring AOP 将优先选择 JDK 动态代理。</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">如果目标对象没有实现任何接口,则会自动切换到 CGLIB 代理。</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">如果要强制使用 CGLIB 代理,可以在启动类或配置类上添加 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">@EnableAspectJAutoProxy(proxyTargetClass = true)</span></code><span leaf=""> 注解即可。</span> </section></li> </ul> </blockquote> <h3 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: flex;"><span style="display: none;"></span><span style="font-size: 20px;color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;font-weight: bold;display: block;"><span leaf="">Spring AOP 的配置使用</span></span><span style="display: none;"></span></h3> <h4 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: block;"><span style="display: none;"></span><span style="font-size: 18px;color: rgb(0, 0, 0);line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: bold;display: block;"><span leaf="">Spring AOP 的使用步骤</span></span><span style="display: none;"></span></h4> <ol style="list-style-type: decimal;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">启用 AOP 支持</span></strong><span leaf="">:在启动类或任意配置类上添加 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">@EnableAspectJAutoProxy</span></code><span leaf=""> 注解。</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">定义切面(Aspect)</span></strong><span leaf="">:创建一个类,使用 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">@Aspect</span></code><span leaf=""> 注解来标记这个类为一个切面,并使用 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">@Component</span></code><span leaf=""> 注解让 Spring 管理这个 Bean。</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">指定切入点(Pointcut)</span></strong><span leaf="">:使用 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">@Pointcut</span></code><span leaf=""> 注解加 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">AspectJ</span></code><span leaf=""> 表达式定义切入点。</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">定义通知(Advice)</span></strong><span leaf="">:定义一个通知,在特定连接点时执行特定逻辑。</span> </section></li> </ol> <blockquote style="margin-top: 20px;margin-bottom: 20px;margin-left: 0px;margin-right: 0px;padding-top: 10px;padding-bottom: 10px;padding-left: 20px;padding-right: 10px;border-top-style: none;border-bottom-style: none;border-left-style: solid;border-right-style: solid;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 1px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgb(150, 84, 181);border-right-color: rgb(150, 84, 181);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;background-attachment: scroll;background-clip: border-box;background-color: rgb(251, 249, 253);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;display: block;overflow-x: auto;overflow-y: auto;"> <span style="display: none;color: rgb(0, 0, 0);font-size: 16px;line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: normal;"></span> <p style="text-indent: 0em;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;margin-top: 0px;margin-right: 0px;margin-bottom: 0px;margin-left: 0px;"><span leaf="">Spring 提供的通知类型有如下几种:</span></p> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">@Before(前置通知)</span></strong><span leaf="">:前置通知是在目标方法调用 </span><strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">之前</span></strong><span leaf=""> 执行的通知。无论目标方法是否抛出异常或正常返回,前置通知都会被执行。</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">@AfterReturning(后置返回通知)</span></strong><span leaf="">:后置返回通知是在目标方法 </span><strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">成功返回后</span></strong><span leaf=""> 执行的通知。只有当目标方法没有抛出异常时,才会触发该通知。</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">@AfterThrowing(抛出异常通知)</span></strong><span leaf="">:抛出异常通知是在目标方法 </span><strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">抛出异常后</span></strong><span leaf=""> 执行的通知。它只会在方法抛出指定类型的异常时触发。</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">@Around(环绕通知)</span></strong><span leaf="">:环绕通知是最强大的一种通知类型,它包围了目标方法的调用。你可以完全控制方法的执行,包括决定是否继续执行方法以及如何处理返回值或异常。</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">@After(后置最终通知)</span></strong><span leaf="">:后置最终通知是在目标方法 </span><strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">完成之后</span></strong><span leaf=""> 执行的通知,不论方法是正常结束还是因为异常而终止。</span> </section></li> </ul> </blockquote> <h4 data-tool="mdnice编辑器" style="margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: block;"><span style="display: none;"></span><span style="font-size: 18px;color: rgb(0, 0, 0);line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: bold;display: block;"><span leaf="">Spring AOP 使用示例</span></span><span style="display: none;"></span></h4> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">启用 AOP 支持</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg k0ue4mipav882cnbmffjvlrxfiaoyowabg1n9gndbfbyylu3av0epdc78k5wnsukhhozztyffw9mdqxuoquchp80rlmqpmiibl 640?wx_fmt="svg&from=appmsg");""></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #61aeee;line-height: 26px;"><span leaf="">@SpringBootApplication</span></span><br><span style="color: #61aeee;line-height: 26px;"><span leaf="">@EnableAspectJAutoProxy</span></span><br><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">class</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">MyApp</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">static</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">main</span></span><span style="line-height: 26px;"><span leaf="">(String[] args)</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> SpringApplication.run(MyApp</span><span style="line-height: 26px;"><span leaf="">.</span><span style="color: #c678dd;line-height: 26px;"><span leaf="">class</span></span><span leaf="">, </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">args</span></span><span leaf="">)</span></span><span leaf="">;</span><br><span leaf=""> }</span><br><span leaf="">}</span><br></code></pre> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">定义切面类</span></p> <pre data-tool="mdnice编辑器" style="border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;text-align: left;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;"><span data-cacheurl="" data-remoteid="" style="display: block;background: none;height: 30px;width: 100%;background-size: 40px;background-repeat: no-repeat;background-color: #282c34;margin-bottom: -7px;border-radius: 5px;background-position: 10px 10px;background-image: url(" https: mmbiz.qpic.cn mmbiz_svg k0ue4mipav882cnbmffjvlrxfiaoyowabg1n9gndbfbyylu3av0epdc78k5wnsukhhozztyffw9mdqxuoquchp80rlmqpmiibl 640?wx_fmt="svg&from=appmsg");""></span><code style="overflow-x: auto;padding: 16px;color: #abb2bf;padding-top: 15px;background: #282c34;border-radius: 5px;display: -webkit-box;font-family: Consolas, Monaco, Menlo, monospace;font-size: 12px;"><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Slf</span></span><span leaf="">4j</span><br><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Aspect</span></span><br><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Component</span></span><br><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">class</span></span><span leaf=""> </span><span style="color: #e6c07b;line-height: 26px;"><span leaf="">AllAdviceAspect</span></span><span leaf=""> </span></span><span leaf="">{</span><br><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 定义切入点,匹配 service 包下的所有方法</span></span><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Pointcut</span></span><span leaf="">(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"execution(* com.example.service..*.*(..))"</span></span><span leaf="">)</span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">serviceLayerExecution</span></span><span style="line-height: 26px;"><span leaf="">()</span></span><span leaf=""> </span></span><span leaf="">{}</span><br><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 前置通知,在方法调用前打印日志</span></span><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Before</span></span><span leaf="">(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"serviceLayerExecution()"</span></span><span leaf="">)</span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">logBefore</span></span><span style="line-height: 26px;"><span leaf="">(JoinPoint joinPoint)</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> log.info(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"Before method execution: {}"</span></span><span leaf="">, joinPoint.getSignature().getName());</span><br><span leaf=""> }</span><br><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 后置返回通知,在方法成功返回后打印日志</span></span><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@AfterReturning</span></span><span leaf="">(pointcut = </span><span style="color: #98c379;line-height: 26px;"><span leaf="">"serviceLayerExecution()"</span></span><span leaf="">, returning = </span><span style="color: #98c379;line-height: 26px;"><span leaf="">"result"</span></span><span leaf="">)</span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">logAfterReturning</span></span><span style="line-height: 26px;"><span leaf="">(JoinPoint joinPoint, Object result)</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> log.info(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"Method returned successfully: {}, Result: {}"</span></span><span leaf="">, joinPoint.getSignature().getName(), result);</span><br><span leaf=""> }</span><br><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 抛出异常通知,在方法抛出异常后打印日志</span></span><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@AfterThrowing</span></span><span leaf="">(pointcut = </span><span style="color: #98c379;line-height: 26px;"><span leaf="">"serviceLayerExecution()"</span></span><span leaf="">, throwing = </span><span style="color: #98c379;line-height: 26px;"><span leaf="">"ex"</span></span><span leaf="">)</span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">logAfterThrowing</span></span><span style="line-height: 26px;"><span leaf="">(JoinPoint joinPoint, Exception ex)</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> log.error(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"An exception was thrown in {}: {}"</span></span><span leaf="">, joinPoint.getSignature().getName(), ex.getMessage());</span><br><span leaf=""> }</span><br><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 后置最终通知,在方法完成之后打印日志,无论是否抛出异常</span></span><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@After</span></span><span leaf="">(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"serviceLayerExecution()"</span></span><span leaf="">)</span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">void</span></span><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">logAfter</span></span><span style="line-height: 26px;"><span leaf="">(JoinPoint joinPoint)</span></span><span leaf=""> </span></span><span leaf="">{</span><br><span leaf=""> log.info(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"After method execution: {}"</span></span><span leaf="">, joinPoint.getSignature().getName());</span><br><span leaf=""> }</span><br><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 环绕通知,包围方法调用,控制方法执行流程</span></span><br><span leaf=""> </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">@Around</span></span><span leaf="">(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"serviceLayerExecution()"</span></span><span leaf="">)</span><br><span leaf=""> </span><span style="line-height: 26px;"><span style="color: #c678dd;line-height: 26px;"><span leaf="">public</span></span><span leaf=""> Object </span><span style="color: #61aeee;line-height: 26px;"><span leaf="">logAround</span></span><span style="line-height: 26px;"><span leaf="">(ProceedingJoinPoint pjp)</span></span><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">throws</span></span><span leaf=""> Throwable </span></span><span leaf="">{</span><br><span leaf=""> log.info(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"Starting around advice for method: {}"</span></span><span leaf="">, pjp.getSignature().getName());</span><br><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">long</span></span><span leaf=""> start = System.currentTimeMillis();</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">try</span></span><span leaf=""> {</span><br><span leaf=""> </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 执行目标方法</span></span><br><span leaf=""> Object result = pjp.proceed();</span><br><span leaf=""> log.info(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"Method {} took {} ms to execute"</span></span><span leaf="">, pjp.getSignature().getName(), System.currentTimeMillis() - start);</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">return</span></span><span leaf=""> result;</span><br><span leaf=""> } </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">catch</span></span><span leaf=""> (Throwable e) {</span><br><span leaf=""> log.error(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"Error during method execution: {}"</span></span><span leaf="">, e.getMessage());</span><br><span leaf=""> </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">throw</span></span><span leaf=""> e; </span><span style="color: #5c6370;font-style: italic;line-height: 26px;"><span leaf="">// 重新抛出异常以便后续处理</span></span><br><span leaf=""> } </span><span style="color: #c678dd;line-height: 26px;"><span leaf="">finally</span></span><span leaf=""> {</span><br><span leaf=""> log.info(</span><span style="color: #98c379;line-height: 26px;"><span leaf="">"Ending around advice for method: {}"</span></span><span leaf="">, pjp.getSignature().getName());</span><br><span leaf=""> }</span><br><span leaf=""> }</span><br><span leaf="">}</span><br></code></pre> <h2 data-tool="mdnice编辑器" style=" margin-top: 30px;margin-bottom: 15px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;align-items: unset;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: flex;flex-direction: unset;float: unset;height: auto;justify-content: center;line-height: 1.5em;overflow-x: unset;overflow-y: unset; text-align: left;text-shadow: none;transform: none;width: 100%;-webkit-box-reflect: unset; "><span style="display: none;"></span><span style=" font-size: 22px;border-bottom-color: rgb(119, 48, 152);color: rgb(119, 48, 152);line-height: 1.5em;letter-spacing: 0em;background-attachment: scroll;background-clip: border-box;background-color: unset;background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: 85%;height: auto;align-items: unset;border-top-style: none;border-bottom-style: solid;border-left-style: none;border-right-style: none;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgb(0, 0, 0);border-left-color: rgb(0, 0, 0);border-right-color: rgb(0, 0, 0);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-left-radius: 0px;border-bottom-right-radius: 0px;box-shadow: none;display: block;font-weight: bold;flex-direction: unset;float: unset;justify-content: unset;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;overflow-x: unset;overflow-y: unset;padding-top: 0px;padding-bottom: 10px;padding-left: 0px;padding-right: 0px; text-align: center;text-indent: 0em;text-shadow: none;transform: none;-webkit-box-reflect: unset; "><span leaf="">三者之间对比</span></span><span style="display: none;"></span></h2> <ul style="list-style-type: disc;margin-top: 8px;margin-bottom: 8px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 25px;padding-right: 0px;color: rgb(0, 0, 0);" class="list-paddingleft-1"> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Filter</span></code><span leaf=""> 是 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Java Servlet</span></code><span leaf=""> 规范的一部分,它工作在 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Servlet</span></code><span leaf=""> 容器层面,是 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Servlet</span></code><span leaf=""> 容器级别的,适用于所有进入应用的 HTTP 请求。</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Interceptor</span></code><span leaf=""> 是 Spring MVC 框架提供的一种请求处理机制,是属于框架级别的。通过 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Interceptor</span></code><span leaf=""> 章节的源码可以看出,</span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Interceptor</span></code><span leaf=""> 工作在 Spring MVC 分发处理请求时,而分发请求的类是 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">DispatcherServlet</span></code><span leaf="">,它是一个 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Servlet</span></code><span leaf="">,根据 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Servlet</span></code><span leaf=""> 规范,</span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Filter</span></code><span leaf=""> 是先于 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Servlet</span></code><span leaf=""> 执行的。所以 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Filter</span></code><span leaf=""> 要比 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Interceptor</span></code><span leaf=""> 优先执行。</span> </section></li> <li> <section style="margin-top: 5px;margin-bottom: 5px;color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;font-weight: normal;"> <span leaf="">Spring AOP 是 Spring 框架提供的面向切面编程的支持,允许我们在不改变原有业务逻辑的前提下,集中处理横切关注点。它的执行时机是在特定的连接点,也就是请求已经到了我们 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">controller</span></code><span leaf=""> 中的某个方法时才会触发,而 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Interceptor</span></code><span leaf=""> 在执行查找到的 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">handler</span></code><span leaf=""> 之前就已经被调用了,所以 </span><code style="background-attachment: scroll;background-clip: border-box;background-color: rgba(27, 31, 35, 0.05);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 2px;margin-right: 2px;padding-top: 2px;padding-bottom: 2px;padding-left: 4px;padding-right: 4px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgb(0, 0, 0);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 4px;border-top-right-radius: 4px;border-bottom-right-radius: 4px;border-bottom-left-radius: 4px;overflow-wrap: break-word;font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;"><span leaf="">Interceptor</span></code><span leaf=""> 要先于 Spring AOP 执行。</span> </section></li> </ul> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">执行顺序如下图:</span></strong></p> <figure data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;display: flex;flex-direction: column;justify-content: center;align-items: center;"> <span leaf=""><img class="rich_pages wxw-img" data-imgfileid="100003275" src="/upload/b3d9b349c7e734c17c83705218cc47a9.png" data-type="png" style="display: block;margin-top: 0px;margin-right: auto;margin-bottom: 0px;margin-left: auto;max-width: 100%;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;object-fit: fill;box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px;"></span> </figure> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">本篇主要基于 SpringBoot 介绍了过滤器、拦截器和 Spring AOP,通过学习其基本知识了解到了它们工作时的执行顺序。实际上,其实无论是过滤器还是拦截器,都可以被视为 AOP 思想的具体实现形式,尽管它们各自工作在不同的层次上。</span></p> <p data-tool="mdnice编辑器" style="color: rgb(90, 90, 90);font-size: 15px;line-height: 1.8em;letter-spacing: 0.02em;text-align: left;text-indent: 0em;margin-top: 10px;margin-bottom: 10px;margin-left: 0px;margin-right: 0px;padding-top: 8px;padding-bottom: 8px;padding-left: 0px;padding-right: 0px;"><span leaf="">您的鼓励对我持续创作非常关键,如果本文对您有帮助,请记得</span><strong style="color: rgb(0, 0, 0);font-weight: bold;background-attachment: scroll;background-clip: border-box;background-color: rgba(0, 0, 0, 0);background-image: none;background-origin: padding-box;background-position-x: 0%;background-position-y: 0%;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;margin-top: 0px;margin-bottom: 0px;margin-left: 0px;margin-right: 0px;padding-top: 0px;padding-bottom: 0px;padding-left: 0px;padding-right: 0px;border-top-style: none;border-bottom-style: none;border-left-style: none;border-right-style: none;border-top-width: 3px;border-bottom-width: 3px;border-left-width: 3px;border-right-width: 3px;border-top-color: rgba(0, 0, 0, 0.4);border-bottom-color: rgba(0, 0, 0, 0.4);border-left-color: rgba(0, 0, 0, 0.4);border-right-color: rgba(0, 0, 0, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><span leaf="">点赞、分享、在看</span></strong><span leaf="">哦~~~谢谢!</span></p> </section> <p style="display: none;"> <mp-style-type data-value="3"></mp-style-type></p>
作者:微信小助手
<section> <span leaf=""><span textstyle="" style="font-size: 16px;font-weight: bold;">结论:</span></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;"> </span><span textstyle="" style="font-size: 16px;font-style: italic;text-decoration: underline;">解析同步效率:</span><span textstyle="" style="font-size: 16px;color: rgb(255, 76, 0);font-weight: bold;font-style: italic;text-decoration: underline;">Flinkcdc完胜 (遥遥领先!!!!!)</span></span> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang=""><code><span leaf=""><span class="code-snippet__plaintext"> Flinkcdc > Canal</span></span></code></pre> </section> <section> <span leaf=""> 选择用哪个?</span> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang=""><code><span leaf=""><span class="code-snippet__plaintext">推荐:Flinkcdc</span></span></code></pre> </section> <section> <span leaf=""><br></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;font-weight: bold;">一、测试对比:</span></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;font-weight: bold;">1.1、版本对比:</span></span> </section> <section> <code><span leaf="" data-pm-slice="1 1 [" codeblock,{data-lang:xml},code,{}]><span textstyle="" style="font-size: 16px;font-weight: bold;">1、Flinkcdc</span></span></code> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="xml"><code><span leaf=""><span class="code-snippet__tag"><span class="code-snippet__plaintext"><</span></span><span class="code-snippet__tag"><span class="code-snippet__name">dependency</span></span><span class="code-snippet__tag"><span class="code-snippet__plaintext">></span></span><span class="code-snippet__plaintext"> </span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__tag"><span class="code-snippet__plaintext"><</span></span><span class="code-snippet__tag"><span class="code-snippet__name">groupId</span></span><span class="code-snippet__tag"><span class="code-snippet__plaintext">></span></span><span class="code-snippet__plaintext">com.ververica</span><span class="code-snippet__tag"><span class="code-snippet__plaintext"><!--/</span--></span><span class="code-snippet__tag"><span class="code-snippet__name">groupId</span></span><span class="code-snippet__tag"><span class="code-snippet__plaintext">></span></span><span class="code-snippet__plaintext"> </span></span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__tag"><span class="code-snippet__plaintext"><</span></span><span class="code-snippet__tag"><span class="code-snippet__name">artifactId</span></span><span class="code-snippet__tag"><span class="code-snippet__plaintext">></span></span><span class="code-snippet__plaintext">flink-connector-mysql-cdc</span><span class="code-snippet__tag"><span class="code-snippet__plaintext"><!--/</span--></span><span class="code-snippet__tag"><span class="code-snippet__name">artifactId</span></span><span class="code-snippet__tag"><span class="code-snippet__plaintext">></span></span><span class="code-snippet__plaintext"> </span></span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__tag"><span class="code-snippet__plaintext"><</span></span><span class="code-snippet__tag"><span class="code-snippet__name">version</span></span><span class="code-snippet__tag"><span class="code-snippet__plaintext">></span></span><span class="code-snippet__plaintext">2.4.0</span><span class="code-snippet__tag"><span class="code-snippet__plaintext"><!--/</span--></span><span class="code-snippet__tag"><span class="code-snippet__name">version</span></span><span class="code-snippet__tag"><span class="code-snippet__plaintext">></span></span></span></span></code><code><span leaf=""><span class="code-snippet__tag"><span class="code-snippet__plaintext"><!--/</span--></span><span class="code-snippet__tag"><span class="code-snippet__name">dependency</span></span><span class="code-snippet__tag"><span class="code-snippet__plaintext">></span></span></span></span></code></pre> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;font-weight: bold;">2、canal:</span></span> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang=""><code><span leaf=""><span class="code-snippet__plaintext">canal.deployer-1.1.5.tar.gz</span></span></code></pre> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;font-weight: bold;">1.2、数据总量:</span></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;font-weight: normal;"> 在MySQL数据库中导入</span><span textstyle="" style="font-size: 16px;color: rgb(255, 0, 0);font-weight: bold;font-style: italic;text-decoration: underline;">数据量为 1.5亿数据(涉及200多个表),4个小时导入完成</span><span textstyle="" style="font-size: 16px;font-weight: normal;">。Flinkcdc和Canal都什么时候同步完成了?</span></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;color: rgb(255, 0, 0);font-style: italic;text-decoration: underline;">注:Flinkcdc 和Canal同时接入同一个库来数据解析并同步数据。</span></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;color: rgb(255, 0, 0);font-weight: bold;font-style: italic;text-decoration: underline;">前提条件:</span></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;color: rgb(0, 82, 255);font-style: italic;text-decoration: underline;">数据:1.5亿</span></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;color: rgb(0, 82, 255);font-style: italic;text-decoration: underline;">导入时长:4个小时</span></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;font-weight: bold;">1、Flinkcdc:</span></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;">解析同步时长:</span><span textstyle="" style="font-size: 16px;color: rgb(255, 76, 0);font-weight: bold;">6个小时</span></span> </section> <section style="text-align: center;" nodeleaf=""> <img class="rich_pages wxw-img" data-imgfileid="100001548" data-ratio="0.2644281217208814" data-s="300,640" src="/upload/ad62b4b758fdf6057dc80640c3f9439f.png" data-type="png" data-w="953" type="block"> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;font-weight: bold;">2、Canal:</span></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;">解析同步时长:</span><span textstyle="" style="font-size: 16px;color: rgb(255, 76, 0);font-weight: bold;">13个小时</span></span> </section> <section style="text-align: center;" nodeleaf=""> <img class="rich_pages wxw-img" data-imgfileid="100001549" data-ratio="0.24310520939734423" data-s="300,640" src="/upload/2af47fa04c74e7642b1d642e84339e25.png" data-type="png" data-w="979" type="block"> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;font-weight: bold;">结论:</span></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;"> 解析同步效率:</span><span class="code-snippet__plaintext">Flinkcdc </span><span textstyle="" style="font-size: 16px;color: rgb(255, 76, 0);font-style: italic;text-decoration: underline;">完胜</span></span> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang=""><code><span leaf=""><span class="code-snippet__plaintext"> Flinkcdc > Canal</span></span></code></pre> </section> <section> <span leaf=""><br></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;font-weight: bold;">1.3、如果现有Canal需升级为Flinkcdc?怎么弄了?(</span><span textstyle="" style="font-size: 18px;color: rgb(255, 0, 0);font-weight: bold;">生产环境</span><span textstyle="" style="font-size: 16px;font-weight: bold;">)</span></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;font-weight: bold;">结论:</span></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;font-weight: bold;">1、数据格式转换:</span></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;font-weight: bold;"> </span><span textstyle="" style="font-size: 16px;color: rgb(0, 82, 255);font-style: italic;text-decoration: underline;">将Flinkcdc的数据格式转换成Canal数据格式。其余都不用变。</span></span> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang=""><code><span leaf=""><span class="code-snippet__plaintext"> FlinkCdcEvent -> CanalEvent</span></span></code></pre> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;font-weight: bold;">2、数据解析后都是Json:</span></span> </section> <section> <span leaf=""><br></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 18px;color: rgb(255, 0, 0);font-weight: bold;"> </span><span textstyle="" style="font-size: 18px;color: rgb(255, 0, 0);font-weight: bold;font-style: italic;text-decoration: underline;">记得用Gson转换。fastjson有坑,不建议用.</span></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 18px;color: rgb(255, 0, 0);font-weight: bold;"> </span><span textstyle="" style="font-size: 18px;color: rgb(255, 0, 0);font-weight: bold;font-style: italic;text-decoration: underline;"> 记得用Gson转换。fastjson有坑,不建议用.</span></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 18px;color: rgb(255, 0, 0);font-weight: bold;"> </span><span textstyle="" style="font-size: 18px;color: rgb(255, 0, 0);font-weight: bold;font-style: italic;text-decoration: underline;"> 记得用Gson转换。fastjson有坑,不建议用.</span></span> </section> <section> <span leaf=""><br></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;font-weight: bold;">1.4、Flinkcdc及Canal数据格式对比:</span></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;font-weight: bold;">1、CanalEvent:</span></span> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="typescript"><code><span leaf=""><span class="code-snippet__keyword">import</span><span class="code-snippet__plaintext"> java.</span><span class="code-snippet__property">util</span><span class="code-snippet__plaintext">.</span><span class="code-snippet__property">List</span><span class="code-snippet__plaintext">;</span></span></code><code><span leaf=""><span class="code-snippet__keyword">import</span><span class="code-snippet__plaintext"> java.</span><span class="code-snippet__property">util</span><span class="code-snippet__plaintext">.</span><span class="code-snippet__property">Map</span><span class="code-snippet__plaintext">;</span></span></code><code><span leaf=""><span class="code-snippet__keyword">public</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">class</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__title">CanalEvent</span><span class="code-snippet__plaintext"> {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">private</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__title">List</span><span class="code-snippet__plaintext"><</span><span class="code-snippet__title">Map</span><span class="code-snippet__plaintext"><</span><span class="code-snippet__title">String</span><span class="code-snippet__plaintext">, </span><span class="code-snippet__title">String</span><span class="code-snippet__plaintext">>> data;</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">private</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__title">String</span><span class="code-snippet__plaintext"> database;</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">private</span><span class="code-snippet__plaintext"> long es;</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">private</span><span class="code-snippet__plaintext"> long id;</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">private</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__built_in">boolean</span><span class="code-snippet__plaintext"> isDdl;</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">private</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__title">Map</span><span class="code-snippet__plaintext"><</span><span class="code-snippet__title">String</span><span class="code-snippet__plaintext">, </span><span class="code-snippet__title">String</span><span class="code-snippet__plaintext">> mysqlType;</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">private</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__title">List</span><span class="code-snippet__plaintext"><</span><span class="code-snippet__title">Map</span><span class="code-snippet__plaintext"><</span><span class="code-snippet__title">String</span><span class="code-snippet__plaintext">, </span><span class="code-snippet__title">String</span><span class="code-snippet__plaintext">>> old;</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">private</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__title">List</span><span class="code-snippet__plaintext"><</span><span class="code-snippet__title">String</span><span class="code-snippet__plaintext">> pkNames;</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">private</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__title">String</span><span class="code-snippet__plaintext"> sql;</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">private</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__title">Map</span><span class="code-snippet__plaintext"><</span><span class="code-snippet__title">String</span><span class="code-snippet__plaintext">, </span><span class="code-snippet__title">Integer</span><span class="code-snippet__plaintext">> sqlType;</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">private</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__title">String</span><span class="code-snippet__plaintext"> table;</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">private</span><span class="code-snippet__plaintext"> long ts;</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">private</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__title">String</span><span class="code-snippet__plaintext"> </span><span class="code-snippet__keyword">type</span><span class="code-snippet__plaintext">;</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__comment">// Getters and setters</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> // toString</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> ...</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">}</span></span></code></pre> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="javascript"><code><span leaf=""><span class="code-snippet__plaintext">{</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"data"</span><span class="code-snippet__plaintext">: [</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"G00002"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"name"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"阿龙大数据"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"province_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"32"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"province"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"江苏省"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"city_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"3201"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"city"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"南京市"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"district_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"320114"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"district"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"雨花台区"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"address"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"科创城23222333444"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"logo_url"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"http://along/icon_112.png"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"slogan"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"欢迎"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"credit_code"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"2343243"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"master_name"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"阿龙"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"master_idcard"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"532524199911304246"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"power_group_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"9996"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"opt_time"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"2021-10-19 17:41:57"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"add_user_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"132"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"add_user_name"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"测试"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"add_time"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"2020-07-27 13:59:34"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"email"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"123456@qq.com"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"master_wechat"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"service_phone"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"13232323232"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"max_shop_num"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"5"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"pay_mode"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"business_license"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"https://image/MXVSeb7Pv4r1f1346237770562140.jpg"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"idcard_front"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"https://image/13uty9yyvrlvWb346237808202139.png"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"idcard_back"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"https:///image/5uA7IblI6r1zoW346237778042125.png"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"cloud_shop_state"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"0"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"expiration_time"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"version_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"company_type"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"0"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"company_property"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"1"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"main_sell"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"introduction"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"contact_name"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"contact_phone"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"certification_name"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"阿龙大数据"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"is_test"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"login_account"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"delete_at"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"0"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"self_invitation_code"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"IN6501"</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> }</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> ],</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"database"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"test"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"es"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">1669010586000</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">8150</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"isDdl"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">false</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"mysqlType"</span><span class="code-snippet__plaintext">: {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(32)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"name"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(64)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"province_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"int(6)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"province"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(32)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"city_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"int(6)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"city"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(32)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"district_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"int(6)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"district"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(64)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"address"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(128)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"logo_url"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(500)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"slogan"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(255)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"credit_code"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(18)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"master_name"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(16)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"master_idcard"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(18)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"power_group_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"bigint(20)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"opt_time"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"datetime"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"add_user_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(32)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"add_user_name"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(32)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"add_time"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"datetime"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"email"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(255)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"master_wechat"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(255)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"service_phone"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(32)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"max_shop_num"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"int(11)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"pay_mode"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"int(1)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"business_license"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(128)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"idcard_front"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(128)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"idcard_back"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(128)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"cloud_shop_state"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"int(1)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"expiration_time"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"datetime"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"version_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"bigint(20)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"company_type"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"tinyint(2)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"company_property"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"int(2)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"main_sell"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(200)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"introduction"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(512)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"contact_name"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(32)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"contact_phone"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(11)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"certification_name"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(64)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"is_test"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"int(1)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"login_account"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"varchar(50)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"delete_at"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"bigint(14)"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"self_invitation_code"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"char(6)"</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> },</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"old"</span><span class="code-snippet__plaintext">: [</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"address"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"北京"</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> }</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> ],</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"pkNames"</span><span class="code-snippet__plaintext">: [</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"id"</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> ],</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"sql"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">""</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"sqlType"</span><span class="code-snippet__plaintext">: {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"name"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"province_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">4</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"province"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"city_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">4</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"city"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"district_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">4</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"district"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"address"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"logo_url"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"slogan"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"credit_code"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"master_name"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"master_idcard"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"power_group_id"</span><span class="code-snippet__plaintext">: -</span><span class="code-snippet__number">5</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"opt_time"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">93</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"add_user_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"add_user_name"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"add_time"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">93</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"email"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"master_wechat"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"service_phone"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"max_shop_num"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">4</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"pay_mode"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">4</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"business_license"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"idcard_front"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"idcard_back"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"cloud_shop_state"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">4</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"expiration_time"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">93</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"version_id"</span><span class="code-snippet__plaintext">: -</span><span class="code-snippet__number">5</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"company_type"</span><span class="code-snippet__plaintext">: -</span><span class="code-snippet__number">6</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"company_property"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">4</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"main_sell"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"introduction"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"contact_name"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"contact_phone"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"certification_name"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"is_test"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">4</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"login_account"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">12</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"delete_at"</span><span class="code-snippet__plaintext">: -</span><span class="code-snippet__number">5</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"self_invitation_code"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">1</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> },</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"table"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"company"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"ts"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">1669010468134</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"type"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"UPDATE"</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">}</span></span></code></pre> </section> <section> <span leaf=""><br></span> </section> <section> <span leaf=""><span textstyle="" style="font-size: 16px;font-weight: bold;">2、FlinkCdcEvent:</span></span> </section> <section class="code-snippet__fix code-snippet__js"> <ul class="code-snippet__line-index code-snippet__js"> </ul> <pre class="code-snippet__js" data-lang="javascript"><code><span leaf=""><span class="code-snippet__plaintext">{</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"before"</span><span class="code-snippet__plaintext">: {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"PF1784570096901248"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"pay_order_no"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"out_no"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"J1784570080435328"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"title"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"充值办卡"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"from_user_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"PG11111"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"from_account_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"1286009802396288"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"user_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"BO1707796995184000"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"account_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"1707895210106496"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"amount"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">13400</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"profit_state"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"profit_time"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">1686758315000</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"refund_state"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"refund_time"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"add_time"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">1686758315000</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"remark"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"充值办卡"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"acct_circle"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"PG11111"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"user_type"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">92</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"from_user_type"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">90</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"company_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"PG11111"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"profit_mode"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"type"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">2</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"parent_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"oc_profit_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"1784570096901248"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"keep_account_from_user_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"keep_account_from_bm_user_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"keep_account_user_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"keep_account_bm_user_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"biz_company_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"PG11111"</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> },</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"after"</span><span class="code-snippet__plaintext">: {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"PF1784570096901248"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"pay_order_no"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"out_no"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"J1784570080435328"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"title"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"充值办卡"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"from_user_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"PG11111"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"from_account_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"1286009802396288"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"user_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"BO1707796995184000"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"account_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"1707895210106496"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"amount"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">13400</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"profit_state"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"profit_time"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">1686758315000</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"refund_state"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"refund_time"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"add_time"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">1686758315000</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"remark"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"充值办卡1"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"acct_circle"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"PG11111"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"user_type"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">92</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"from_user_type"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">90</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"company_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"PG11111"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"profit_mode"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"type"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">2</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"parent_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"oc_profit_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"1784570096901248"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"keep_account_from_user_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"keep_account_from_bm_user_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"keep_account_user_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"keep_account_bm_user_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"biz_company_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"PG11111"</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> },</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"source"</span><span class="code-snippet__plaintext">: {</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"version"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"1.6.4.Final"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"connector"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"mysql"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"name"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"mysql_binlog_source"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"ts_ms"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">1686734882000</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"snapshot"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"false"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"db"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"cloud_test"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"sequence"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"table"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"acct_profit"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"server_id"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">1</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"gtid"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"file"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"mysql-bin.000514"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"pos"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">650576218</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"row"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">0</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"thread"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"query"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> },</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"op"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__string">"u"</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"ts_ms"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__number">1686734882689</span><span class="code-snippet__plaintext">,</span></span></code><code><span leaf=""><span class="code-snippet__plaintext"> </span><span class="code-snippet__string">"transaction"</span><span class="code-snippet__plaintext">: </span><span class="code-snippet__literal">null</span></span></code><code><span leaf=""><span class="code-snippet__plaintext">}</span></span></code></pre> </section> <section> <span leaf=""><br></span> </section> <section> <span leaf=""><br></span> </section> <section style="text-align: center;"> <span leaf=""> <span textstyle="" style="color: rgb(172, 57, 255);"> </span><span textstyle="" style="font-size: 18px;color: rgb(172, 57, 255);font-weight: bold;">记录每一份热爱,让美好永远陪伴。</span></span> </section>